From 4c00811f217342145ed5f653f6b66543b2f106cc Mon Sep 17 00:00:00 2001 From: shenxianpeng Date: Tue, 26 May 2026 20:31:52 +0300 Subject: [PATCH 1/4] feat: integrate open-delivery-spec/validate-action@v1 into DevSecOps workflows Add ODS Validate job to all GitHub Actions workflows (repo + templates) that validates branch naming, commit messages, and PR descriptions against Open Delivery Spec standards. Non-conformant submissions trigger gate failure. Closes #11 --- .github/workflows/devsecops.yml | 24 +++++++++++++++++---- CHANGELOG.md | 8 +++++++ src/cast_cli/templates/go/devsecops.yml | 24 ++++++++++++++++++--- src/cast_cli/templates/nodejs/devsecops.yml | 24 ++++++++++++++++++--- src/cast_cli/templates/python/devsecops.yml | 24 ++++++++++++++++++--- templates/go/devsecops.yml | 24 ++++++++++++++++++--- templates/nodejs/devsecops.yml | 24 ++++++++++++++++++--- templates/python/devsecops.yml | 24 ++++++++++++++++++--- 8 files changed, 154 insertions(+), 22 deletions(-) diff --git a/.github/workflows/devsecops.yml b/.github/workflows/devsecops.yml index c96db0e..91388ca 100644 --- a/.github/workflows/devsecops.yml +++ b/.github/workflows/devsecops.yml @@ -8,7 +8,8 @@ # 4. Container Security — Trivy (skipped if no Dockerfile) # 5. Code Quality — Ruff # 6. Template Lint — yamllint on templates/**/*.yml -# 7. Security Gate — blocks merge on critical findings +# 7. ODS Validate — open-delivery-spec/validate-action +# 8. Security Gate — blocks merge on critical findings name: CAST DevSecOps @@ -143,11 +144,24 @@ jobs: # Only lint pure workflow YAML files in .github/workflows/. run: yamllint -d relaxed .github/workflows/*.yml - # ── 7. Security Gate ─────────────────────────────────────────────────────── + # ── 7. ODS Validate ──────────────────────────────────────────────────────── + ods: + name: ODS Validate + runs-on: ubuntu-latest + steps: + - uses: open-delivery-spec/validate-action@v1 + with: + check: all + branch_name: ${{ github.head_ref }} + commit_message: ${{ github.event.head_commit.message }} + pr_body: ${{ github.event.pull_request.body }} + strict: "true" + + # ── 8. Security Gate ─────────────────────────────────────────────────────── gate: name: Security Gate runs-on: ubuntu-latest - needs: [secrets, sast, sca, quality] + needs: [secrets, sast, sca, quality, ods] if: always() steps: - name: Evaluate results @@ -156,10 +170,12 @@ jobs: echo "sast : ${{ needs.sast.result }}" echo "sca : ${{ needs.sca.result }}" echo "quality : ${{ needs.quality.result }}" + echo "ods : ${{ needs.ods.result }}" if [[ "${{ needs.secrets.result }}" == "failure" || "${{ needs.sast.result }}" == "failure" || - "${{ needs.sca.result }}" == "failure" ]]; then + "${{ needs.sca.result }}" == "failure" || + "${{ needs.ods.result }}" == "failure" ]]; then echo "❌ Security gate failed — merge blocked" exit 1 fi diff --git a/CHANGELOG.md b/CHANGELOG.md index e07fec6..15de1d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,14 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ## [Unreleased] +### Added + +- **ODS Validate** — integrated `open-delivery-spec/validate-action@v1` into all + DevSecOps workflows (`.github/workflows/devsecops.yml` and all templates). + Validates branch naming, commit messages, and PR descriptions against + [Open Delivery Spec](https://github.com/open-delivery-spec/spec) standards. + Non-conformant submissions block the security gate. + ## [0.1.1] — 2026-03-24 ### Changed diff --git a/src/cast_cli/templates/go/devsecops.yml b/src/cast_cli/templates/go/devsecops.yml index fa4f1fb..f6ddb30 100644 --- a/src/cast_cli/templates/go/devsecops.yml +++ b/src/cast_cli/templates/go/devsecops.yml @@ -7,7 +7,8 @@ # 3. SCA — govulncheck # 4. Container Security — Trivy (skipped if no Dockerfile) # 5. Code Quality — staticcheck -# 6. Security Gate — conftest policy evaluation on SARIF findings +# 6. ODS Validate — open-delivery-spec/validate-action +# 7. Security Gate — conftest policy evaluation on SARIF findings name: CAST DevSecOps @@ -131,11 +132,24 @@ jobs: go install honnef.co/go/tools/cmd/staticcheck@latest staticcheck ./... - # ── 6. Security Gate ─────────────────────────────────────────────────────── + # ── 6. ODS Validate ──────────────────────────────────────────────────────── + ods: + name: ODS Validate + runs-on: ubuntu-latest + steps: + - uses: open-delivery-spec/validate-action@v1 + with: + check: all + branch_name: ${{ github.head_ref }} + commit_message: ${{ github.event.head_commit.message }} + pr_body: ${{ github.event.pull_request.body }} + strict: "true" + + # ── 7. Security Gate ─────────────────────────────────────────────────────── gate: name: Security Gate runs-on: ubuntu-latest - needs: [secrets, sast, sca, container, quality] + needs: [secrets, sast, sca, container, quality, ods] if: always() steps: - uses: actions/checkout@v4 @@ -193,6 +207,10 @@ REGO echo "❌ SCA (govulncheck) failed" GATE_FAILED=1 fi + if [[ "${{ needs.ods.result }}" == "failure" ]]; then + echo "❌ ODS Validate failed" + GATE_FAILED=1 + fi if [ "$GATE_FAILED" -eq 1 ]; then echo "❌ Security gate blocked merge" diff --git a/src/cast_cli/templates/nodejs/devsecops.yml b/src/cast_cli/templates/nodejs/devsecops.yml index bdbd4e2..da33183 100644 --- a/src/cast_cli/templates/nodejs/devsecops.yml +++ b/src/cast_cli/templates/nodejs/devsecops.yml @@ -7,7 +7,8 @@ # 3. SCA — npm audit # 4. Container Security — Trivy (skipped if no Dockerfile) # 5. Code Quality — ESLint -# 6. Security Gate — conftest policy evaluation on SARIF findings +# 6. ODS Validate — open-delivery-spec/validate-action +# 7. Security Gate — conftest policy evaluation on SARIF findings name: CAST DevSecOps @@ -131,11 +132,24 @@ jobs: - name: ESLint run: npx eslint . --ext .js,.jsx,.ts,.tsx --max-warnings 0 - # ── 6. Security Gate ─────────────────────────────────────────────────────── + # ── 6. ODS Validate ──────────────────────────────────────────────────────── + ods: + name: ODS Validate + runs-on: ubuntu-latest + steps: + - uses: open-delivery-spec/validate-action@v1 + with: + check: all + branch_name: ${{ github.head_ref }} + commit_message: ${{ github.event.head_commit.message }} + pr_body: ${{ github.event.pull_request.body }} + strict: "true" + + # ── 7. Security Gate ─────────────────────────────────────────────────────── gate: name: Security Gate runs-on: ubuntu-latest - needs: [secrets, sast, sca, container, quality] + needs: [secrets, sast, sca, container, quality, ods] if: always() steps: - uses: actions/checkout@v4 @@ -193,6 +207,10 @@ REGO echo "❌ SCA (npm audit) failed" GATE_FAILED=1 fi + if [[ "${{ needs.ods.result }}" == "failure" ]]; then + echo "❌ ODS Validate failed" + GATE_FAILED=1 + fi if [ "$GATE_FAILED" -eq 1 ]; then echo "❌ Security gate blocked merge" diff --git a/src/cast_cli/templates/python/devsecops.yml b/src/cast_cli/templates/python/devsecops.yml index f38912f..54cbd3c 100644 --- a/src/cast_cli/templates/python/devsecops.yml +++ b/src/cast_cli/templates/python/devsecops.yml @@ -7,7 +7,8 @@ # 3. SCA — pip-audit # 4. Container Security — Trivy (skipped if no Dockerfile) # 5. Code Quality — Ruff -# 6. Security Gate — blocks merge on critical findings +# 6. ODS Validate — open-delivery-spec/validate-action +# 7. Security Gate — blocks merge on critical findings name: CAST DevSecOps @@ -125,11 +126,24 @@ jobs: - uses: actions/checkout@v4 - uses: astral-sh/ruff-action@v1 - # ── 6. Security Gate ─────────────────────────────────────────────────────── + # ── 6. ODS Validate ──────────────────────────────────────────────────────── + ods: + name: ODS Validate + runs-on: ubuntu-latest + steps: + - uses: open-delivery-spec/validate-action@v1 + with: + check: all + branch_name: ${{ github.head_ref }} + commit_message: ${{ github.event.head_commit.message }} + pr_body: ${{ github.event.pull_request.body }} + strict: "true" + + # ── 7. Security Gate ─────────────────────────────────────────────────────── gate: name: Security Gate runs-on: ubuntu-latest - needs: [secrets, sast, sca, container, quality] + needs: [secrets, sast, sca, container, quality, ods] if: always() steps: - uses: actions/checkout@v4 @@ -187,6 +201,10 @@ REGO echo "❌ SCA (pip-audit) failed" GATE_FAILED=1 fi + if [[ "${{ needs.ods.result }}" == "failure" ]]; then + echo "❌ ODS Validate failed" + GATE_FAILED=1 + fi if [ "$GATE_FAILED" -eq 1 ]; then echo "❌ Security gate blocked merge" diff --git a/templates/go/devsecops.yml b/templates/go/devsecops.yml index 523a6da..c463413 100644 --- a/templates/go/devsecops.yml +++ b/templates/go/devsecops.yml @@ -7,7 +7,8 @@ # 3. SCA — govulncheck # 4. Container Security — Trivy (skipped if no Dockerfile) # 5. Code Quality — staticcheck -# 6. Security Gate — conftest policy evaluation on SARIF findings +# 6. ODS Validate — open-delivery-spec/validate-action +# 7. Security Gate — conftest policy evaluation on SARIF findings name: CAST DevSecOps @@ -131,11 +132,24 @@ jobs: go install honnef.co/go/tools/cmd/staticcheck@latest staticcheck ./... - # ── 6. Security Gate ─────────────────────────────────────────────────────── + # ── 6. ODS Validate ──────────────────────────────────────────────────────── + ods: + name: ODS Validate + runs-on: ubuntu-latest + steps: + - uses: open-delivery-spec/validate-action@v1 + with: + check: all + branch_name: ${{ github.head_ref }} + commit_message: ${{ github.event.head_commit.message }} + pr_body: ${{ github.event.pull_request.body }} + strict: "true" + + # ── 7. Security Gate ─────────────────────────────────────────────────────── gate: name: Security Gate runs-on: ubuntu-latest - needs: [secrets, sast, sca, container, quality] + needs: [secrets, sast, sca, container, quality, ods] if: always() steps: - uses: actions/checkout@v4 @@ -193,6 +207,10 @@ REGO echo "❌ SCA (govulncheck) failed" GATE_FAILED=1 fi + if [[ "${{ needs.ods.result }}" == "failure" ]]; then + echo "❌ ODS Validate failed" + GATE_FAILED=1 + fi if [ "$GATE_FAILED" -eq 1 ]; then echo "❌ Security gate blocked merge" diff --git a/templates/nodejs/devsecops.yml b/templates/nodejs/devsecops.yml index 0f3f5af..9964dfc 100644 --- a/templates/nodejs/devsecops.yml +++ b/templates/nodejs/devsecops.yml @@ -7,7 +7,8 @@ # 3. SCA — npm audit # 4. Container Security — Trivy (skipped if no Dockerfile) # 5. Code Quality — ESLint -# 6. Security Gate — conftest policy evaluation on SARIF findings +# 6. ODS Validate — open-delivery-spec/validate-action +# 7. Security Gate — conftest policy evaluation on SARIF findings name: CAST DevSecOps @@ -131,11 +132,24 @@ jobs: - name: ESLint run: npx eslint . --ext .js,.jsx,.ts,.tsx --max-warnings 0 - # ── 6. Security Gate ─────────────────────────────────────────────────────── + # ── 6. ODS Validate ──────────────────────────────────────────────────────── + ods: + name: ODS Validate + runs-on: ubuntu-latest + steps: + - uses: open-delivery-spec/validate-action@v1 + with: + check: all + branch_name: ${{ github.head_ref }} + commit_message: ${{ github.event.head_commit.message }} + pr_body: ${{ github.event.pull_request.body }} + strict: "true" + + # ── 7. Security Gate ─────────────────────────────────────────────────────── gate: name: Security Gate runs-on: ubuntu-latest - needs: [secrets, sast, sca, container, quality] + needs: [secrets, sast, sca, container, quality, ods] if: always() steps: - uses: actions/checkout@v4 @@ -193,6 +207,10 @@ REGO echo "❌ SCA (npm audit) failed" GATE_FAILED=1 fi + if [[ "${{ needs.ods.result }}" == "failure" ]]; then + echo "❌ ODS Validate failed" + GATE_FAILED=1 + fi if [ "$GATE_FAILED" -eq 1 ]; then echo "❌ Security gate blocked merge" diff --git a/templates/python/devsecops.yml b/templates/python/devsecops.yml index 28d8c27..21876dc 100644 --- a/templates/python/devsecops.yml +++ b/templates/python/devsecops.yml @@ -7,7 +7,8 @@ # 3. SCA — pip-audit # 4. Container Security — Trivy (skipped if no Dockerfile) # 5. Code Quality — Ruff -# 6. Security Gate — blocks merge on critical findings +# 6. ODS Validate — open-delivery-spec/validate-action +# 7. Security Gate — blocks merge on critical findings name: CAST DevSecOps @@ -125,11 +126,24 @@ jobs: - uses: actions/checkout@v4 - uses: astral-sh/ruff-action@v1 - # ── 6. Security Gate ─────────────────────────────────────────────────────── + # ── 6. ODS Validate ──────────────────────────────────────────────────────── + ods: + name: ODS Validate + runs-on: ubuntu-latest + steps: + - uses: open-delivery-spec/validate-action@v1 + with: + check: all + branch_name: ${{ github.head_ref }} + commit_message: ${{ github.event.head_commit.message }} + pr_body: ${{ github.event.pull_request.body }} + strict: "true" + + # ── 7. Security Gate ─────────────────────────────────────────────────────── gate: name: Security Gate runs-on: ubuntu-latest - needs: [secrets, sast, sca, container, quality] + needs: [secrets, sast, sca, container, quality, ods] if: always() steps: - uses: actions/checkout@v4 @@ -187,6 +201,10 @@ REGO echo "❌ SCA (pip-audit) failed" GATE_FAILED=1 fi + if [[ "${{ needs.ods.result }}" == "failure" ]]; then + echo "❌ ODS Validate failed" + GATE_FAILED=1 + fi if [ "$GATE_FAILED" -eq 1 ]; then echo "❌ Security gate blocked merge" From f41353a85af9e52ec2bab6868a01d3dd1e3d81f9 Mon Sep 17 00:00:00 2001 From: shenxianpeng Date: Tue, 26 May 2026 20:46:15 +0300 Subject: [PATCH 2/4] chore: add ODS-compliant PR template Add .github/PULL_REQUEST_TEMPLATE.md with required ODS sections (Type, AI Disclosure, Testing, Checklist) so future PRs automatically include all mandatory fields. --- .github/PULL_REQUEST_TEMPLATE.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..8d5691f --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,27 @@ +## Summary + + +## Type + +- [ ] Feature +- [ ] Bug fix +- [ ] Documentation +- [ ] Refactor +- [ ] CI / Pipeline + +## AI Disclosure + +- [ ] This PR contains AI-generated code +- AI Tool: + +## Changes + + +## Testing + + +## Checklist + +- [ ] Branch follows ODS naming convention +- [ ] PR description follows ODS spec +- [ ] No breaking changes From 2afe5c0a7a568ee093c8a750e1511ddb2de4f8f1 Mon Sep 17 00:00:00 2001 From: shenxianpeng Date: Tue, 26 May 2026 20:49:47 +0300 Subject: [PATCH 3/4] docs: add CAST DevSecOps and ODS validated badges Show pipeline status (including ODS validation) and ODS compliance in both English and Chinese READMEs. --- README.md | 3 ++- README.zh.md | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b06ed55..7cfe782 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,8 @@ [![PyPI version](https://img.shields.io/pypi/v/castops.svg)](https://pypi.org/project/castops/) [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE) -[![GitHub Actions](https://img.shields.io/badge/GitHub%20Actions-ready-2088FF?logo=github-actions&logoColor=white)](https://github.com/castops/cast/actions) +[![CAST DevSecOps](https://github.com/castops/cast-cli/actions/workflows/devsecops.yml/badge.svg)](https://github.com/castops/cast-cli/actions/workflows/devsecops.yml) +[![ODS](https://img.shields.io/badge/ODS-validated-brightgreen)](https://github.com/open-delivery-spec/spec) English | [中文](README.zh.md) diff --git a/README.zh.md b/README.zh.md index feb9c68..8deb164 100644 --- a/README.zh.md +++ b/README.zh.md @@ -7,7 +7,8 @@ [![PyPI version](https://img.shields.io/pypi/v/castops.svg)](https://pypi.org/project/castops/) [![Python](https://img.shields.io/pypi/pyversions/castops.svg)](https://pypi.org/project/castops/) [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE) -[![GitHub Actions](https://img.shields.io/badge/GitHub%20Actions-ready-2088FF?logo=github-actions&logoColor=white)](https://github.com/castops/cast/actions) +[![CAST DevSecOps](https://github.com/castops/cast-cli/actions/workflows/devsecops.yml/badge.svg)](https://github.com/castops/cast-cli/actions/workflows/devsecops.yml) +[![ODS](https://img.shields.io/badge/ODS-validated-brightgreen)](https://github.com/open-delivery-spec/spec) [English](README.md) | 中文 From c7f8cbb39e13af45411b957584ab2b3f996db021 Mon Sep 17 00:00:00 2001 From: shenxianpeng Date: Tue, 26 May 2026 20:54:34 +0300 Subject: [PATCH 4/4] Revert "docs: add CAST DevSecOps and ODS validated badges" This reverts commit 2afe5c0a7a568ee093c8a750e1511ddb2de4f8f1. --- README.md | 3 +-- README.zh.md | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7cfe782..b06ed55 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,7 @@ [![PyPI version](https://img.shields.io/pypi/v/castops.svg)](https://pypi.org/project/castops/) [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE) -[![CAST DevSecOps](https://github.com/castops/cast-cli/actions/workflows/devsecops.yml/badge.svg)](https://github.com/castops/cast-cli/actions/workflows/devsecops.yml) -[![ODS](https://img.shields.io/badge/ODS-validated-brightgreen)](https://github.com/open-delivery-spec/spec) +[![GitHub Actions](https://img.shields.io/badge/GitHub%20Actions-ready-2088FF?logo=github-actions&logoColor=white)](https://github.com/castops/cast/actions) English | [中文](README.zh.md) diff --git a/README.zh.md b/README.zh.md index 8deb164..feb9c68 100644 --- a/README.zh.md +++ b/README.zh.md @@ -7,8 +7,7 @@ [![PyPI version](https://img.shields.io/pypi/v/castops.svg)](https://pypi.org/project/castops/) [![Python](https://img.shields.io/pypi/pyversions/castops.svg)](https://pypi.org/project/castops/) [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE) -[![CAST DevSecOps](https://github.com/castops/cast-cli/actions/workflows/devsecops.yml/badge.svg)](https://github.com/castops/cast-cli/actions/workflows/devsecops.yml) -[![ODS](https://img.shields.io/badge/ODS-validated-brightgreen)](https://github.com/open-delivery-spec/spec) +[![GitHub Actions](https://img.shields.io/badge/GitHub%20Actions-ready-2088FF?logo=github-actions&logoColor=white)](https://github.com/castops/cast/actions) [English](README.md) | 中文