diff --git a/.github/workflows/branch-target-check.yml b/.github/workflows/branch-target-check.yml new file mode 100644 index 0000000..bec2a31 --- /dev/null +++ b/.github/workflows/branch-target-check.yml @@ -0,0 +1,48 @@ +# SPDX-License-Identifier: Apache-2.0 + +# Enforces the feature-branch → dev → main development workflow. +# +# When `main` is the default branch, GitHub pre-selects it as the PR base in the +# UI and in `gh pr create`. This check fails immediately with a clear, actionable +# message if a PR targets main from any branch other than `dev` or `release/v.*`, +# saving developers from a confusing "branch is locked" error or a misleading +# "prerelease version detected" message from version-check.yml. +# +# Allowed sources for PRs to main: +# dev — the normal integration branch +# release/v.* — release-train branches created by release-train.yml (must start with a digit) +# +# Please do not attempt to edit this flow without the direct consent from the DevOps team. +# This file is managed centrally. + +name: Branch target check + +permissions: + contents: read + +on: + pull_request: + branches: + - main + +jobs: + check-source-branch: + if: github.actor != 'dependabot[bot]' && github.actor != 'dependabot-preview[bot]' + runs-on: ubuntu-latest + steps: + - name: Verify PR source branch is dev or release/v.* + env: + SOURCE: ${{ github.head_ref }} + run: | + if [[ "$SOURCE" == "dev" || "$SOURCE" == release/v[0-9]* ]]; then + echo "✅ Source branch '$SOURCE' is a valid base for a PR to main." + else + echo "❌ PRs to main must come from 'dev' or a 'release/v.*' branch (e.g. release/v1.2)." + echo " This PR is from '$SOURCE'." + echo "" + echo " If you are working on a feature or fix, please retarget this PR to 'dev':" + echo " gh pr edit --base dev" + echo "" + echo " Only 'dev' → main (via release-train.yml) and 'release/v.*' → main merges are permitted." + exit 1 + fi diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml new file mode 100644 index 0000000..3a711fb --- /dev/null +++ b/.github/workflows/scorecard.yml @@ -0,0 +1,58 @@ +# SPDX-License-Identifier: Apache-2.0 + +# Please do not attempt to edit this flow without the direct consent from the DevOps team. This file is managed centrally. + +name: Scorecard supply-chain security + +on: + branch_protection_rule: + schedule: + - cron: '15 16 * * 0' + push: + branches: + - main + - dev + +# Scorecard workflow restrictions (enforced when publish_results=true): +# - No workflow-level env vars or defaults +# - No workflow-level write permissions (read-all is fine) +# - Only the scorecard job may use id-token: write +permissions: read-all + +jobs: + analysis: + name: Scorecard analysis + runs-on: ubuntu-latest + permissions: + # Required for uploading SARIF results to the code-scanning dashboard + security-events: write + # Required for GitHub OIDC token used by publish_results + id-token: write + + steps: + - name: "Checkout code" + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + + - name: "Run analysis" + uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3 + with: + results_file: results.sarif + results_format: sarif + # Publish results (badge + REST API) only when running on the default + # branch or on a schedule/branch-protection event. Dev-branch runs + # still score the repo but do not overwrite the published badge. + publish_results: ${{ github.ref == 'refs/heads/main' || github.event_name == 'schedule' || github.event_name == 'branch_protection_rule' }} + + - name: "Upload artifact" + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + with: + name: SARIF file + path: results.sarif + retention-days: 5 + + - name: "Upload to code-scanning" + uses: github/codeql-action/upload-sarif@38697555549f1db7851b81482ff19f1fa5c4fedc # v4.34.1 + with: + sarif_file: results.sarif