From b5e91a70ea497a1085a18438c657d1fdc1c05ba9 Mon Sep 17 00:00:00 2001 From: Anthony Gomez Date: Wed, 24 Jun 2026 17:28:50 -0400 Subject: [PATCH 1/4] ci: refactor goreleaser workflows to use GitHub app tokens - Replace personal access token with ephemeral tokens from Fastly DevEx Workflows GitHub app - Remove unused AUR (Arch User Repository) configuration and related secrets handling - Implement two-phase Homebrew publishing: generate formula on draft, publish on release - Add artifact storage for Homebrew formula between draft and publish workflows - Update publish_release workflow name to reflect expanded scope beyond NPM - Clean up .gitignore to remove aur_key reference This ensures Homebrew formula is only published when the GitHub release is officially published (not on draft creation), enabling proper version control and allowing users to rollback via homebrew-tap git history. Resolves the timing issue where AUR and Homebrew were publishing during draft creation instead of waiting for official release publication. --- .github/workflows/publish_release.yml | 43 +++++++++++++++++++++- .github/workflows/tag_to_draft_release.yml | 37 ++++++++++--------- .gitignore | 3 -- .goreleaser.yml | 39 +------------------- 4 files changed, 62 insertions(+), 60 deletions(-) diff --git a/.github/workflows/publish_release.yml b/.github/workflows/publish_release.yml index cd80e8db3..0c1be779a 100644 --- a/.github/workflows/publish_release.yml +++ b/.github/workflows/publish_release.yml @@ -1,4 +1,4 @@ -name: NPM Release +name: Publish Release on: workflow_dispatch: release: @@ -10,6 +10,47 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: false jobs: + homebrew_release: + name: Publish Homebrew formula + runs-on: ubuntu-latest + steps: + - name: "Generate a GitHub token" + id: github-token + uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 + with: + client-id: ${{ vars.GH_APP_ID }} + private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} + owner: ${{ github.repository_owner }} + repositories: | + ${{ github.repository }} + homebrew-tap + permission-contents: write + - name: "Download Homebrew formula artifact" + uses: dawidd6/action-download-artifact@bf251b5aa9c2f7eeb574a96ee720e24f801b7c11 # v6 + with: + workflow: tag_to_draft_release.yml + name: homebrew-formula-${{ github.event.release.tag_name }} + github_token: ${{ steps.github-token.outputs.token }} + - name: "Checkout homebrew-tap repository" + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + repository: fastly/homebrew-tap + path: homebrew-tap + persist-credentials: false + - name: "Copy formula to homebrew-tap repository" + run: | + cp fastly.rb homebrew-tap/Formula/fastly.rb + - name: "Commit and push Homebrew formula" + working-directory: homebrew-tap + env: + RELEASE_TAG: ${{ github.event.release.tag_name }} + GH_TOKEN: ${{ steps.github-token.outputs.token }} + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add Formula/fastly.rb + git commit -m "Update fastly formula to ${RELEASE_TAG}" + git push https://x-access-token:${GH_TOKEN}@github.com/fastly/homebrew-tap.git npm_release: name: Publish npm packages runs-on: ubuntu-latest diff --git a/.github/workflows/tag_to_draft_release.yml b/.github/workflows/tag_to_draft_release.yml index 8a603460b..305435b1f 100644 --- a/.github/workflows/tag_to_draft_release.yml +++ b/.github/workflows/tag_to_draft_release.yml @@ -13,10 +13,22 @@ jobs: goreleaser: name: Run goreleaser runs-on: ubuntu-latest + permissions: + contents: write steps: + - name: "Generate a GitHub token" + id: github-token + uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 + with: + client-id: ${{ vars.GH_APP_ID }} + private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} + owner: ${{ github.repository_owner }} + repositories: ${{ github.repository }} + permission-contents: write - name: "Checkout code" uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: + token: ${{ steps.github-token.outputs.token }} persist-credentials: false - name: "Fetch unshallow repo" run: git fetch --prune --unshallow @@ -33,22 +45,6 @@ jobs: rustflags: "" - name: "Generate static app config" run: make config - # Passing the raw SSH private key causes an error: - # Load key "/tmp/id_*": invalid format - # - # Testing locally we discovered that storing in a file and passing the file path works. - # - # NOTE: - # The file aur_key must be added to .gitignore otherwise a 'dirty state' error is triggered in goreleaser. - # https://github.com/goreleaser/goreleaser/blob/9505cf7054b05a6e9a4a36f806d525bc33660e9e/www/docs/errors/dirty.md - # - # You must also reduce the permissions from a default of 0644 to 600 to avoid a 'bad permissions' error. - - name: "Store AUR_KEY in local file" - env: - AUR_KEY_SECRET: ${{ secrets.AUR_KEY }} - run: | - printf '%s\n' "$AUR_KEY_SECRET" > "$GITHUB_WORKSPACE/aur_key" - chmod 600 "$GITHUB_WORKSPACE/aur_key" - name: "Run GoReleaser" uses: goreleaser/goreleaser-action@5daf1e915a5f0af01ddbcd89a43b8061ff4f1a89 # v7.2.2 with: @@ -57,5 +53,10 @@ jobs: version: '~> v2' args: release --clean env: - AUR_KEY: '${{ github.workspace }}/aur_key' - GITHUB_TOKEN: ${{ secrets.RELEASE_GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ steps.github-token.outputs.token }} + - name: "Upload Homebrew formula as artifact" + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: homebrew-formula-${{ github.ref_name }} + path: dist/fastly.rb + if-no-files-found: error diff --git a/.gitignore b/.gitignore index 5370bf679..8600936ce 100644 --- a/.gitignore +++ b/.gitignore @@ -60,9 +60,6 @@ build/ # Ignore application configuration vendor/ -# Ignore generated file for AUR_KEY which is passed to goreleaser as an environment variable. -aur_key - # Ignore static config that is embedded into the CLI # All Makefile targets use the 'config' as a prerequisite (which generates the config) pkg/config/config.toml diff --git a/.goreleaser.yml b/.goreleaser.yml index eda2343e4..a7015deb6 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -72,43 +72,6 @@ archives: <<: *archive_defaults wrap_in_directory: false formats: [zip] -# https://goreleaser.com/customization/aur/ -aurs: - - homepage: "https://github.com/fastly/cli" - description: "A CLI for interacting with the Fastly platform" - maintainers: - - 'oss@fastly.com' - license: "Apache license 2.0" - skip_upload: auto - provides: - - fastly - conflicts: - - fastly - - # The SSH private key that should be used to commit to the Git repository. - # This can either be a path or the key contents. - # - # WARNING: do not expose your private key in the config file! - private_key: '{{ .Env.AUR_KEY }}' - - # The AUR Git URL for this package. - # Defaults to empty. - git_url: 'ssh://aur@aur.archlinux.org/fastly-bin.git' - - # List of packages that are not needed for the software to function, - # but provide additional features. - # - # Must be in the format `package: short description of the extra functionality`. - # - # Defaults to empty. - optdepends: - - 'viceroy: for running service locally' - - # The value to be passed to `GIT_SSH_COMMAND`. - # - # - # Defaults to `ssh -i {{ .KeyPath }} -o StrictHostKeyChecking=accept-new -F /dev/null`. - git_ssh_command: 'ssh -i {{ .KeyPath }} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -F /dev/null' # https://goreleaser.com/customization/homebrew/ brews: @@ -117,7 +80,7 @@ brews: repository: owner: fastly name: homebrew-tap - skip_upload: auto + skip_upload: true # Formula will be uploaded by publish_release workflow description: A CLI for interacting with the Fastly platform homepage: https://github.com/fastly/cli directory: Formula From 02fec6fac9dde43ac6c503d502f1f9d5073fa5e6 Mon Sep 17 00:00:00 2001 From: Anthony Gomez Date: Fri, 26 Jun 2026 10:34:15 -0400 Subject: [PATCH 2/4] remove extra token gen added to fix over zealous zizmor warnings --- .github/workflows/publish_release.yml | 5 ++--- .github/workflows/tag_to_draft_release.yml | 14 +------------- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/.github/workflows/publish_release.yml b/.github/workflows/publish_release.yml index 0c1be779a..fbae3a289 100644 --- a/.github/workflows/publish_release.yml +++ b/.github/workflows/publish_release.yml @@ -35,8 +35,8 @@ jobs: uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: repository: fastly/homebrew-tap + token: ${{ steps.github-token.outputs.token }} path: homebrew-tap - persist-credentials: false - name: "Copy formula to homebrew-tap repository" run: | cp fastly.rb homebrew-tap/Formula/fastly.rb @@ -44,13 +44,12 @@ jobs: working-directory: homebrew-tap env: RELEASE_TAG: ${{ github.event.release.tag_name }} - GH_TOKEN: ${{ steps.github-token.outputs.token }} run: | git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" git add Formula/fastly.rb git commit -m "Update fastly formula to ${RELEASE_TAG}" - git push https://x-access-token:${GH_TOKEN}@github.com/fastly/homebrew-tap.git + git push npm_release: name: Publish npm packages runs-on: ubuntu-latest diff --git a/.github/workflows/tag_to_draft_release.yml b/.github/workflows/tag_to_draft_release.yml index 305435b1f..6975d1b4b 100644 --- a/.github/workflows/tag_to_draft_release.yml +++ b/.github/workflows/tag_to_draft_release.yml @@ -16,20 +16,8 @@ jobs: permissions: contents: write steps: - - name: "Generate a GitHub token" - id: github-token - uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 - with: - client-id: ${{ vars.GH_APP_ID }} - private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} - owner: ${{ github.repository_owner }} - repositories: ${{ github.repository }} - permission-contents: write - name: "Checkout code" uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - token: ${{ steps.github-token.outputs.token }} - persist-credentials: false - name: "Fetch unshallow repo" run: git fetch --prune --unshallow - name: "Install Go" @@ -53,7 +41,7 @@ jobs: version: '~> v2' args: release --clean env: - GITHUB_TOKEN: ${{ steps.github-token.outputs.token }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: "Upload Homebrew formula as artifact" uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: From 51a09ab829bd464fc92b4753a208eb99ef29527f Mon Sep 17 00:00:00 2001 From: Anthony Gomez Date: Fri, 26 Jun 2026 11:39:48 -0400 Subject: [PATCH 3/4] add explicit persist credentials --- .github/workflows/publish_release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/publish_release.yml b/.github/workflows/publish_release.yml index fbae3a289..ebecd3103 100644 --- a/.github/workflows/publish_release.yml +++ b/.github/workflows/publish_release.yml @@ -36,6 +36,7 @@ jobs: with: repository: fastly/homebrew-tap token: ${{ steps.github-token.outputs.token }} + persist-credentials: true path: homebrew-tap - name: "Copy formula to homebrew-tap repository" run: | From 2ad63c263ea8ffaa72f07dd458b17c1abd84094f Mon Sep 17 00:00:00 2001 From: Anthony Gomez Date: Fri, 26 Jun 2026 11:41:50 -0400 Subject: [PATCH 4/4] add back persist credentials false --- .github/workflows/tag_to_draft_release.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/tag_to_draft_release.yml b/.github/workflows/tag_to_draft_release.yml index 6975d1b4b..6be0e76b0 100644 --- a/.github/workflows/tag_to_draft_release.yml +++ b/.github/workflows/tag_to_draft_release.yml @@ -18,6 +18,8 @@ jobs: steps: - name: "Checkout code" uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false - name: "Fetch unshallow repo" run: git fetch --prune --unshallow - name: "Install Go"