From 53b52cff51c87eaee1a4fcd68d6c318f700ae3a5 Mon Sep 17 00:00:00 2001 From: ckyrouac Date: Wed, 6 Aug 2025 15:25:02 -0400 Subject: [PATCH] ci: Refactor release action to use app and create-pull-request This uses the token generated in the GitHub app that has a limited scope. Also refactors the commit/push steps to use the create-pull-request action rather than manually committing and pushing. This simplifies the token usage when committing/pushing. Signed-off-by: ckyrouac --- .github/workflows/release.yml | 56 ++++++++------- .github/workflows/scheduled-release.yml | 94 +++++++++---------------- 2 files changed, 65 insertions(+), 85 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 03b152a21..a16ce105c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,40 +11,46 @@ jobs: release: name: Create Release if: | - (github.event_name == 'pull_request' && + (github.event_name == 'pull_request' && github.event.pull_request.merged == true && contains(github.event.pull_request.labels.*.name, 'release')) runs-on: ubuntu-latest container: quay.io/coreos-assembler/fcos-buildroot:testing-devel steps: + - uses: actions/create-github-app-token@v2 + id: app-token + with: + app-id: ${{ secrets.APP_ID }} + private-key: ${{ secrets.APP_PRIVATE_KEY }} + - name: Checkout repository uses: actions/checkout@v4 with: fetch-depth: 0 - token: ${{ secrets.GITHUB_TOKEN }} - + token: ${{ steps.app-token.outputs.token }} + - name: Extract version id: extract_version run: | # Extract version from crates/lib/Cargo.toml VERSION=$(cargo read-manifest --manifest-path crates/lib/Cargo.toml | jq -r '.version') - + # Validate version format if ! echo "$VERSION" | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' >/dev/null; then echo "Error: Invalid version format in Cargo.toml: $VERSION" exit 1 fi - + echo "Extracted version: $VERSION" echo "version=$VERSION" >> $GITHUB_OUTPUT echo "TAG_NAME=v$VERSION" >> $GITHUB_OUTPUT - + - name: Install deps run: ./ci/installdeps.sh - + - name: Mark git checkout as safe run: git config --global --add safe.directory "$GITHUB_WORKSPACE" - + - name: Import GPG key if: github.event_name != 'push' uses: crazy-max/ghaction-import-gpg@v6 @@ -54,13 +60,13 @@ jobs: git_user_signingkey: true git_commit_gpgsign: true git_tag_gpgsign: true - + - name: Create and push tag if: github.event_name != 'push' run: | VERSION="${{ steps.extract_version.outputs.version }}" TAG_NAME="v$VERSION" - + if git rev-parse "$TAG_NAME" >/dev/null 2>&1; then echo "Tag $TAG_NAME already exists" exit 0 @@ -68,27 +74,27 @@ jobs: git tag -s -m "Release $VERSION" "$TAG_NAME" git push origin "$TAG_NAME" - + echo "Successfully created and pushed tag $TAG_NAME" - + git checkout "$TAG_NAME" - + - name: Install vendor tool run: cargo install cargo-vendor-filterer - + - name: Cache Dependencies uses: Swatinem/rust-cache@v2 with: key: "release" - + - name: Run cargo xtask package run: cargo xtask package - + - name: Create Release id: create_release uses: actions/create-release@v1 env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} with: tag_name: ${{ steps.extract_version.outputs.TAG_NAME }} release_name: Release ${{ steps.extract_version.outputs.TAG_NAME }} @@ -96,30 +102,30 @@ jobs: prerelease: false body: | ## bootc ${{ steps.extract_version.outputs.version }} - + ### Changes - + Auto-generated release notes will be populated here. - + ### Assets - + - `bootc-${{ steps.extract_version.outputs.version }}-vendor.tar.zstd` - Vendored dependencies archive - `bootc-${{ steps.extract_version.outputs.version }}.tar.zstd` - Source archive - + - name: Upload vendor archive uses: actions/upload-release-asset@v1 env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} with: upload_url: ${{ steps.create_release.outputs.upload_url }} asset_path: ./target/bootc-${{ steps.extract_version.outputs.version }}-vendor.tar.zstd asset_name: bootc-${{ steps.extract_version.outputs.version }}-vendor.tar.zstd asset_content_type: application/zstd - + - name: Upload source archive uses: actions/upload-release-asset@v1 env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} with: upload_url: ${{ steps.create_release.outputs.upload_url }} asset_path: ./target/bootc-${{ steps.extract_version.outputs.version }}.tar.zstd diff --git a/.github/workflows/scheduled-release.yml b/.github/workflows/scheduled-release.yml index cb268fa7c..15025ce55 100644 --- a/.github/workflows/scheduled-release.yml +++ b/.github/workflows/scheduled-release.yml @@ -22,15 +22,22 @@ jobs: runs-on: ubuntu-latest container: quay.io/coreos-assembler/fcos-buildroot:testing-devel steps: + - uses: actions/create-github-app-token@v2 + id: app-token + with: + app-id: ${{ secrets.APP_ID }} + private-key: ${{ secrets.APP_PRIVATE_KEY }} + - name: Checkout repository uses: actions/checkout@v4 with: fetch-depth: 0 - token: ${{ secrets.GITHUB_TOKEN }} - + token: ${{ steps.app-token.outputs.token }} + persist-credentials: false + - name: Mark git checkout as safe run: git config --global --add safe.directory "$GITHUB_WORKSPACE" - + - name: Check if it's time for a release id: check_schedule run: | @@ -39,7 +46,7 @@ jobs: echo "should_release=true" >> $GITHUB_OUTPUT exit 0 fi - + START_DATE="2025-08-04" # start of a 3 week sprint START_TIMESTAMP=$(date -d "$START_DATE" +%s) CURRENT_TIMESTAMP=$(date +%s) @@ -47,21 +54,21 @@ jobs: ADJUSTED_TIMESTAMP=$((CURRENT_TIMESTAMP + 43200)) DAYS_SINCE_START=$(( (ADJUSTED_TIMESTAMP - START_TIMESTAMP) / 86400 )) WEEKS_SINCE_START=$(( DAYS_SINCE_START / 7 )) - + echo "Days since start date ($START_DATE): $DAYS_SINCE_START" echo "Weeks since start date: $WEEKS_SINCE_START" - + # Release every 3 weeks if [ $WEEKS_SINCE_START -gt 0 ] && [ $((WEEKS_SINCE_START % 3)) -eq 0 ]; then echo "should_release=true" >> $GITHUB_OUTPUT else echo "should_release=false" >> $GITHUB_OUTPUT fi - + - name: Install deps if: steps.check_schedule.outputs.should_release == 'true' run: ./ci/installdeps.sh - + - name: Import GPG key if: steps.check_schedule.outputs.should_release == 'true' uses: crazy-max/ghaction-import-gpg@v6 @@ -71,8 +78,8 @@ jobs: git_user_signingkey: true git_commit_gpgsign: true git_tag_gpgsign: true - - - name: Create release commit + + - name: Generate release changes id: create_commit if: steps.check_schedule.outputs.should_release == 'true' env: @@ -98,64 +105,31 @@ jobs: cargo update --workspace cargo xtask update-generated - git commit -am "Release $VERSION" echo "VERSION=$VERSION" >> $GITHUB_OUTPUT - - - name: Create release branch - if: steps.check_schedule.outputs.should_release == 'true' - id: create_branch - env: - VERSION: ${{ steps.create_commit.outputs.VERSION }} - run: | - BRANCH_NAME="release-${VERSION}" - git checkout -b "$BRANCH_NAME" - echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT - - - name: Push branch - if: steps.check_schedule.outputs.should_release == 'true' - env: - BRANCH_NAME: ${{ steps.create_branch.outputs.branch_name }} - run: | - git push origin "${BRANCH_NAME}" - + - name: Create Pull Request - if: steps.check_schedule.outputs.should_release == 'true' - uses: actions/github-script@v7 + uses: peter-evans/create-pull-request@v7 env: VERSION: ${{ steps.create_commit.outputs.VERSION }} - BRANCH_NAME: ${{ steps.create_branch.outputs.branch_name }} with: - script: | - const version = process.env.VERSION; - const branchName = process.env.BRANCH_NAME; - - const { data: pr } = await github.rest.pulls.create({ - owner: context.repo.owner, - repo: context.repo.repo, - title: `Release ${version}`, - body: `## Release ${version} - + token: ${{ steps.app-token.outputs.token }} + signoff: true + sign-commits: true + title: "Release ${{ env.VERSION }}" + commit-message: "Release ${{ env.VERSION }}" + branch: "release-${{ env.VERSION }}" + delete-branch: true + labels: release + body: | + ## Release ${{ env.VERSION }} + This is an automated release PR created by the scheduled release workflow. - + ### Release Process - + 1. Review the changes in this PR 2. Ensure all tests pass 3. Merge the PR 4. The release tag will be automatically created and signed when this PR is merged - - The release workflow will automatically trigger when the tag is pushed.`, - head: branchName, - base: 'main', - draft: false - }); - - // Add the release label - await github.rest.issues.addLabels({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: pr.number, - labels: ['release'] - }); - - console.log(`Created PR #${pr.number}: ${pr.html_url}`); + + The release workflow will automatically trigger when the tag is pushed.