diff --git a/.github/chainguard/release-tag.sts.yaml b/.github/chainguard/release-tag.sts.yaml new file mode 100644 index 0000000..3cfc7b5 --- /dev/null +++ b/.github/chainguard/release-tag.sts.yaml @@ -0,0 +1,12 @@ +# Policy for: .github/workflows/release-tag.yml in DataDog/pup +issuer: https://token.actions.githubusercontent.com +subject: repo:DataDog/pup:pull_request + +claim_pattern: + event_name: pull_request + job_workflow_ref: DataDog/pup/\.github/workflows/release-tag\.yml@refs/pull/[0-9]+/merge + ref: refs/pull/[0-9]+/merge + repository: DataDog/pup + +permissions: + contents: write diff --git a/.github/chainguard/release.sts.yaml b/.github/chainguard/release.sts.yaml index ce07ec6..10e8efb 100644 --- a/.github/chainguard/release.sts.yaml +++ b/.github/chainguard/release.sts.yaml @@ -1,6 +1,6 @@ # Policy for: .github/workflows/release-prepare.yml in DataDog/pup issuer: https://token.actions.githubusercontent.com -subject: repo:DataDog/pup:environment:release +subject: repo:DataDog/pup:ref:refs/heads/main claim_pattern: event_name: schedule|workflow_dispatch @@ -10,3 +10,4 @@ claim_pattern: permissions: contents: write + pull_requests: write diff --git a/.github/workflows/release-prepare.yml b/.github/workflows/release-prepare.yml index aab6128..dc6db34 100644 --- a/.github/workflows/release-prepare.yml +++ b/.github/workflows/release-prepare.yml @@ -48,14 +48,15 @@ jobs: fi # --------------------------------------------------------------------------- - # Release: bump, commit to main, tag. Triggers release.yml via the tag push. + # Release: bump Cargo.toml/Cargo.lock on a release/ branch and open a PR. + # Merging the PR triggers release-tag.yml, which creates the tag and triggers + # release.yml. # --------------------------------------------------------------------------- release: - name: Bump, Commit, Tag + name: Open Release PR needs: check if: needs.check.outputs.proceed == 'true' runs-on: ubuntu-latest - environment: release steps: - uses: DataDog/dd-octo-sts-action@96a25462dbcb10ebf0bfd6e2ccc917d2ab235b9a # v1.0.4 id: octo-sts @@ -66,7 +67,6 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - token: ${{ steps.octo-sts.outputs.token }} - name: Compute next version id: version @@ -82,19 +82,28 @@ jobs: esac NEW_VERSION="${MAJOR}.${MINOR}.${PATCH}" NEW_TAG="v${NEW_VERSION}" + BRANCH="release/${NEW_TAG}" echo "current-tag=${CURRENT_TAG}" >> "$GITHUB_OUTPUT" echo "new-version=${NEW_VERSION}" >> "$GITHUB_OUTPUT" echo "new-tag=${NEW_TAG}" >> "$GITHUB_OUTPUT" + echo "branch=${BRANCH}" >> "$GITHUB_OUTPUT" echo "Current: ${CURRENT_TAG}" echo "Next: ${NEW_TAG} (${BUMP} bump)" - name: Preflight check + env: + GH_TOKEN: ${{ steps.octo-sts.outputs.token }} + NEW_TAG: ${{ steps.version.outputs.new-tag }} + BRANCH: ${{ steps.version.outputs.branch }} run: | - NEW_TAG="${{ steps.version.outputs.new-tag }}" if git tag -l "$NEW_TAG" | grep -q .; then echo "::error::Tag '${NEW_TAG}' already exists." exit 1 fi + if gh api "repos/${GITHUB_REPOSITORY}/git/refs/heads/${BRANCH}" >/dev/null 2>&1; then + echo "::error::Branch '${BRANCH}' already exists." + exit 1 + fi - name: Install Rust run: | @@ -126,26 +135,66 @@ jobs: - name: Refresh Cargo.lock run: cargo check --quiet 2>&1 | grep -v "^$" || true - - name: Commit to main and tag + - name: Create release branch via API (signed commit) + id: commit + env: + GH_TOKEN: ${{ steps.octo-sts.outputs.token }} + NEW_TAG: ${{ steps.version.outputs.new-tag }} + CURRENT_TAG: ${{ steps.version.outputs.current-tag }} + NEW_VERSION: ${{ steps.version.outputs.new-version }} + BRANCH: ${{ steps.version.outputs.branch }} run: | - NEW_TAG="${{ steps.version.outputs.new-tag }}" - CURRENT_TAG="${{ steps.version.outputs.current-tag }}" - NEW_VERSION="${{ steps.version.outputs.new-version }}" - - git config user.name "dd-octo-sts[bot]" - git config user.email "dd-octo-sts[bot]@users.noreply.github.com" - - git add Cargo.toml Cargo.lock - git commit -m "$(cat <> "$GITHUB_OUTPUT" + echo "Created signed commit ${COMMIT_SHA} on ${BRANCH}" + + - name: Open Release PR + env: + GH_TOKEN: ${{ steps.octo-sts.outputs.token }} + NEW_TAG: ${{ steps.version.outputs.new-tag }} + CURRENT_TAG: ${{ steps.version.outputs.current-tag }} + BRANCH: ${{ steps.version.outputs.branch }} + run: | + BODY=$(printf 'Automated version bump from %s to %s.\n\nMerging this PR triggers `release-tag.yml`, which creates the `%s` tag and in turn triggers `release.yml` (goreleaser).' \ + "${CURRENT_TAG}" "${NEW_TAG}" "${NEW_TAG}") + gh pr create \ + --base main \ + --head "${BRANCH}" \ + --title "chore(release): bump version to ${NEW_TAG}" \ + --body "${BODY}" diff --git a/.github/workflows/release-tag.yml b/.github/workflows/release-tag.yml new file mode 100644 index 0000000..af997f7 --- /dev/null +++ b/.github/workflows/release-tag.yml @@ -0,0 +1,45 @@ +name: Tag Release + +on: + pull_request: + types: [closed] + +permissions: + id-token: write + contents: read + +jobs: + tag: + name: Create release tag + if: > + github.event.pull_request.merged == true && + startsWith(github.event.pull_request.head.ref, 'release/') && + github.event.pull_request.head.repo.full_name == github.repository + runs-on: ubuntu-latest + steps: + - uses: DataDog/dd-octo-sts-action@96a25462dbcb10ebf0bfd6e2ccc917d2ab235b9a # v1.0.4 + id: octo-sts + with: + scope: datadog/pup + policy: release-tag + + - name: Create tag + env: + GH_TOKEN: ${{ steps.octo-sts.outputs.token }} + HEAD_REF: ${{ github.event.pull_request.head.ref }} + MERGE_SHA: ${{ github.event.pull_request.merge_commit_sha }} + run: | + set -euo pipefail + TAG_NAME="${HEAD_REF#release/}" + if [[ ! "$TAG_NAME" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "::error::Invalid tag name '${TAG_NAME}' derived from head_ref '${HEAD_REF}'" + exit 1 + fi + if gh api "repos/${GITHUB_REPOSITORY}/git/refs/tags/${TAG_NAME}" >/dev/null 2>&1; then + echo "::error::Tag '${TAG_NAME}' already exists." + exit 1 + fi + gh api "repos/${GITHUB_REPOSITORY}/git/refs" \ + -f ref="refs/tags/${TAG_NAME}" \ + -f sha="${MERGE_SHA}" + echo "Created tag ${TAG_NAME} → ${MERGE_SHA}"