-
Notifications
You must be signed in to change notification settings - Fork 0
governance(tags): add tag rulesets + tag gate workflow #51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| name: Tag Gate | ||
|
|
||
| on: | ||
| push: | ||
| tags: | ||
| - 'v*' | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| gate: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | ||
| with: | ||
| fetch-depth: 0 | ||
|
|
||
| - name: Setup .NET | ||
| uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4 | ||
| with: | ||
| dotnet-version: | | ||
| 8.0.x | ||
| 10.0.102 | ||
|
|
||
| - name: Gate - validate tag format (stable/rc) | ||
| shell: bash | ||
| run: | | ||
| set -euo pipefail | ||
| TAG="${GITHUB_REF_NAME}" | ||
|
|
||
| STABLE_RE='^v[0-9]+\.[0-9]+\.[0-9]+$' | ||
| RC_RE='^v[0-9]+\.[0-9]+\.[0-9]+-rc\.[0-9]+$' | ||
|
|
||
| if [[ "$TAG" =~ $STABLE_RE ]]; then | ||
| echo "OK: stable tag $TAG" | ||
| elif [[ "$TAG" =~ $RC_RE ]]; then | ||
| echo "OK: rc tag $TAG" | ||
| else | ||
| echo "FAIL: invalid tag format: $TAG" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| - name: Gate - derive tag outputs (SSOT) | ||
| shell: bash | ||
| env: | ||
| RELEASE_TAG: ${{ github.ref_name }} | ||
| run: bash tools/ci/release/derive_tag_outputs.sh | ||
|
Comment on lines
+45
to
+49
|
||
|
|
||
| - name: Evidence | ||
| shell: bash | ||
| run: | | ||
| set -euo pipefail | ||
| mkdir -p artifacts/tag-gate | ||
| printf '%s\n' "${GITHUB_REF_NAME}" > artifacts/tag-gate/tag.txt | ||
|
|
||
| - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 | ||
| if: always() | ||
| with: | ||
| name: tag-gate-evidence | ||
| path: artifacts/tag-gate/ | ||
| if-no-files-found: error | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,45 @@ | ||||||||||||||||
| # POLICY: GitHub Tag Rulesets `tags-stable` + `tags-rc` | ||||||||||||||||
|
||||||||||||||||
|
|
||||||||||||||||
| ## Scope / Target | ||||||||||||||||
| Tags are SSOT for publish. Patterns: | ||||||||||||||||
| - stable: `v*` (exclude `v*-rc.*` if UI supports excludes) | ||||||||||||||||
| - rc: `v*-rc.*` | ||||||||||||||||
|
|
||||||||||||||||
| ## Rulesets (GitHub UI) | ||||||||||||||||
| Create rulesets at https://github.com/tomtastisch/FileClassifier/settings/rules/new?target=tag | ||||||||||||||||
|
|
||||||||||||||||
| ### Ruleset `tags-stable` | ||||||||||||||||
| - Target: tag refs | ||||||||||||||||
| - Pattern: | ||||||||||||||||
| - include: `v*` | ||||||||||||||||
| - exclude: `v*-rc.*` (only if UI supports excludes; otherwise `tags-rc` is stricter and will match rc tags too) | ||||||||||||||||
| - Enforcement: Active (fail-closed) | ||||||||||||||||
| - Bypass: minimal (Admins or small Maintainer team). No broad bot/app bypass unless explicitly required. | ||||||||||||||||
| - Rules to enable (depending on UI availability): | ||||||||||||||||
| - Restrict/Prevent deletions | ||||||||||||||||
| - Restrict/Prevent updates / force pushes / moving tags | ||||||||||||||||
| - (optional) Restrict creations (only if you want to limit who can create release tags) | ||||||||||||||||
| - (optional) Require signed commits / signed tags (only if available) | ||||||||||||||||
| - (later) Require status checks (enable only after tag workflows exist and are stable) | ||||||||||||||||
|
|
||||||||||||||||
| ### Ruleset `tags-rc` | ||||||||||||||||
| - Target: tag refs | ||||||||||||||||
| - Pattern: `v*-rc.*` | ||||||||||||||||
| - Enforcement and bypass: same as `tags-stable` | ||||||||||||||||
| - Rules: | ||||||||||||||||
| - Restrict/Prevent deletions | ||||||||||||||||
| - Restrict/Prevent updates / force pushes / moving tags | ||||||||||||||||
| - (optional) Restrict creations | ||||||||||||||||
| - (optional) Require signed commits / signed tags | ||||||||||||||||
| - Require status checks once the rc tag workflow is stable (RC is fail-closed) | ||||||||||||||||
|
|
||||||||||||||||
| ## Expected behaviour | ||||||||||||||||
|
||||||||||||||||
| ## Expected behaviour | |
| ## Expected behavior |
Copilot
AI
Feb 14, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to the rollout plan in the documentation (line 43-44), publish pipelines should be wired to depend on the tag gate using 'needs: tag-gate' or via 'workflow_run' on success. However, the release.yml workflow still only references 'needs: version-policy' (release.yml:99) and doesn't reference this new tag-gate job. The tag-gate workflow will run independently but won't block the release workflow if it fails.
Copilot
AI
Feb 14, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This policy document is missing the standard "RoC-Bezug" (Rules of Compliance reference) section that appears in other governance policy documents. See examples in docs/governance/001_POLICY_CI.MD lines 52-57 and docs/governance/002_POLICY_LABELING.MD lines 24-28. This section should reference relevant rule files like artifact_contract.yaml, docs_drift.yaml, and shell_safety.yaml if applicable.
| 4. Enable status checks for tags only once the checks exist and are stable. | |
| 4. Enable status checks for tags only once the checks exist and are stable. | |
| ## RoC-Bezug | |
| - `rules/artifact_contract.yaml` | |
| - `rules/docs_drift.yaml` | |
| - `rules/shell_safety.yaml` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tag validation regex patterns here are more restrictive than the regex in
tools/ci/release/derive_tag_outputs.sh(line 6). The derive_tag_outputs.sh script uses^v([0-9]+)\.([0-9]+)\.([0-9]+)(-([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?$which allows any alphanumeric prerelease identifiers, while this workflow only acceptsv*-rc.*format for RC tags. This means tags likev1.0.0-beta.1orv1.0.0-alphawould pass the gate step calling derive_tag_outputs.sh but fail the tag format validation step. Consider either aligning the patterns or documenting why they differ.