diff --git a/.github/release-please-config.json b/.github/release-please-config.json index 49fcd84f3c..361a9c3b5f 100644 --- a/.github/release-please-config.json +++ b/.github/release-please-config.json @@ -9,6 +9,7 @@ "bump-minor-pre-major": true, "bump-patch-for-minor-pre-major": true, "draft": true, + "force-tag-creation": true, "changelog-sections": [ { "type": "feat", "section": "Features" }, { "type": "fix", "section": "Bug Fixes" }, diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 26fb5fcde5..de8691f27f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -22,57 +22,9 @@ jobs: config-file: .github/release-please-config.json manifest-file: .github/.release-please-manifest.json - # Draft releases don't create git tags (GitHub only creates tags when - # a release is published). Create the tag explicitly via API so the - # tag push event triggers Docker/CLI workflows. Uses RELEASE_PLEASE_TOKEN - # (PAT) because GITHUB_TOKEN tag pushes don't trigger workflows. - - name: Create git tag for draft release - if: steps.release.outputs.releases_created == 'true' - env: - GH_TOKEN: ${{ secrets.RELEASE_PLEASE_TOKEN }} - TAG_NAME: ${{ steps.release.outputs.tag_name || steps.release.outputs['.--tag_name'] }} - TAG_SHA: ${{ steps.release.outputs.sha || steps.release.outputs['.--sha'] }} - run: | - # Guard: fail fast if release-please didn't provide tag metadata - if [ -z "$TAG_NAME" ] || [ -z "$TAG_SHA" ]; then - echo "::error::Missing tag metadata from release-please outputs (TAG_NAME=$TAG_NAME, TAG_SHA=$TAG_SHA)" - exit 1 - fi - - echo "Creating tag $TAG_NAME at $TAG_SHA" - - # Atomic create: attempt POST unconditionally. Inspect response to - # distinguish "already exists" from genuine validation errors. - RESPONSE_FILE="$(mktemp)" - HTTP_CODE=$(curl -s -o "$RESPONSE_FILE" -w '%{http_code}' \ - -X POST \ - -H "Authorization: token $GH_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - "https://api.github.com/repos/$GITHUB_REPOSITORY/git/refs" \ - -d "{\"ref\":\"refs/tags/$TAG_NAME\",\"sha\":\"$TAG_SHA\"}") - RESPONSE_BODY=$(cat "$RESPONSE_FILE") - rm -f "$RESPONSE_FILE" - - case "$HTTP_CODE" in - 201) - echo "Tag $TAG_NAME created successfully." - ;; - 409) - echo "Tag $TAG_NAME already exists — skipping." - ;; - 422) - if echo "$RESPONSE_BODY" | grep -qi "Reference already exists"; then - echo "Tag $TAG_NAME already exists — skipping." - else - echo "::error::Failed to create tag $TAG_NAME (HTTP 422): $RESPONSE_BODY" - exit 1 - fi - ;; - *) - echo "::error::Failed to create tag $TAG_NAME (HTTP $HTTP_CODE): $RESPONSE_BODY" - exit 1 - ;; - esac + # Tag creation is handled by Release Please via force-tag-creation: true + # in the config. Uses RELEASE_PLEASE_TOKEN (PAT) so tag pushes trigger + # downstream workflows (Docker, CLI). # When Release Please creates/updates a release PR, update the BSL # Change Date to 3 years from today. The date update ships as part diff --git a/CLAUDE.md b/CLAUDE.md index 0cbb6be6a7..8e50756ac9 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -274,7 +274,7 @@ site/ # Astro landing page (synthorg.io) - **DAST**: `.github/workflows/dast.yml` — ZAP API scan against the backend OpenAPI spec on push to main + weekly schedule. Builds backend image locally, starts container, runs ZAP. Results available as workflow artifacts (no SARIF — action v0.10.0 lacks native SARIF output). Not on PRs (too slow). - **Socket.dev**: GitHub App — supply chain attack detection on PRs (typosquatting, malware, suspicious ownership changes, obfuscated code). No config file needed, auto-comments on PRs. - **CLA**: `.github/workflows/cla.yml` — Contributor License Agreement signature check on PRs via `contributor-assistant/github-action`. Triggers on `pull_request_target` and `issue_comment`. Skips Dependabot. Signatures stored in `.github/cla-signatures.json` on the `cla-signatures` branch (unprotected, so the action can commit directly). -- **Release**: `.github/workflows/release.yml` — Release Please (Google) auto-creates a release PR on every push to main. Merging the release PR creates a git tag (`vX.Y.Z`) + **draft** GitHub Release with changelog. Tag push triggers Docker and CLI workflows to attach assets to the draft. Uses `RELEASE_PLEASE_TOKEN` secret (PAT/GitHub App token) so tag creation triggers downstream workflows (GITHUB_TOKEN cannot). Config in `.github/release-please-config.json` (`"draft": true`) and `.github/.release-please-manifest.json`. After creating/updating a release PR, auto-updates the BSL Change Date in LICENSE to 3 years ahead. +- **Release**: `.github/workflows/release.yml` — Release Please (Google) auto-creates a release PR on every push to main. Merging the release PR creates a git tag (`vX.Y.Z`) via `force-tag-creation: true` and a **draft** GitHub Release with changelog. Tag push triggers Docker and CLI workflows to attach assets to the draft. Uses `RELEASE_PLEASE_TOKEN` secret (PAT/GitHub App token) so tag creation triggers downstream workflows (GITHUB_TOKEN cannot). Config in `.github/release-please-config.json` (`"draft": true`, `"force-tag-creation": true`) and `.github/.release-please-manifest.json`. After creating/updating a release PR, auto-updates the BSL Change Date in LICENSE to 3 years ahead. - **Finalize Release**: `.github/workflows/finalize-release.yml` — publishes draft releases created by Release Please. Triggers on `workflow_run` completion of Docker and CLI workflows. Verifies that both workflows succeeded for the associated tag before publishing the draft. Extracts CLI checksums, CLI cosign verification, and container verification data from HTML comments embedded by the CLI and Docker workflows, and assembles them into a combined Verification section in the release notes. Guards against PR-triggered runs (`event != 'pull_request'`). Handles TOCTOU races (concurrent publish attempts exit cleanly). Immutable releases are enabled on the repo — once published, release assets and body cannot be modified. ## Dependencies