diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e3a983a..cb2aaa5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -3,6 +3,10 @@ name: Release on: push: tags: ["v*"] + + # Dispatch the release workflow for an old tag. + # Useful to backfill previous releases when adding a new publiser, + # or to retry a publisher having fixed a bug in one. workflow_dispatch: inputs: tag: @@ -12,36 +16,33 @@ on: permissions: contents: read +concurrency: + group: release-${{ inputs.tag || github.ref_name }} + jobs: goreleaser: runs-on: ubuntu-latest permissions: contents: write # upload release artifacts packages: write # push to ghcr.io - id-token: write # attest artifacts + id-token: write # attest artifacts, npm trusted publishing attestations: write steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: - # Empty on a tag push, where the triggering ref is already the tag. - # Dispatched runs are privileged, so the input can only name a tag, - # never a branch or a pull request. ref: ${{ inputs.tag && format('refs/tags/{0}', inputs.tag) || '' }} fetch-depth: 0 persist-credentials: false - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 with: go-version-file: go.mod - - if: github.event_name == 'push' - uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0 - - if: github.event_name == 'push' - uses: docker/login-action@371161bbe7024a29a25c5e19bfcbc0804fe9ad2c # v4.5.2 + - uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0 + - uses: docker/login-action@371161bbe7024a29a25c5e19bfcbc0804fe9ad2c # v4.5.2 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Generate GitHub App token - if: github.event_name == 'push' id: app-token uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 with: @@ -55,76 +56,67 @@ jobs: - uses: goreleaser/goreleaser-action@f06c13b6b1a9625abc9e6e439d9c05a8f2190e94 # v7.2.3 with: version: "~> v2" - # A dispatched run only needs dist/ populated so the npm packages can - # be assembled from it, so it rebuilds the tag's binaries and archives - # nothing. Those binaries won't be byte-identical to the ones already - # released - go.mod asks for Go 1.26, so setup-go resolves whatever - # patch is current - which is why nothing else is republished here. - args: ${{ github.event_name == 'workflow_dispatch' && 'build --clean' || 'release --clean' }} + args: release --clean env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} HOMEBREW_TAP_GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} # Attests every file listed in the checksum file. - - if: github.event_name == 'push' - uses: actions/attest@508db95dd578ae2727ebd6217d5ba78e4fbda05d # v4.2.1 + - uses: actions/attest@508db95dd578ae2727ebd6217d5ba78e4fbda05d # v4.2.1 with: subject-checksums: ./dist/checksums.txt - - if: github.event_name == 'push' - uses: actions/attest@508db95dd578ae2727ebd6217d5ba78e4fbda05d # v4.2.1 + - uses: actions/attest@508db95dd578ae2727ebd6217d5ba78e4fbda05d # v4.2.1 with: subject-checksums: ./dist/digests.txt - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 with: node-version: 24 # npm >= 11.5.1 required for OIDC trusted publishing - # TODO: switch to goreleaser-npm-publisher-action once https://github.com/evg4b/goreleaser-npm-publisher/pull/26 is released - # Prebuilt dist committed on the fork branch - - name: Fetch goreleaser-npm-publisher - run: | - git clone https://github.com/khvn26/goreleaser-npm-publisher "$RUNNER_TEMP/gnp" - git -C "$RUNNER_TEMP/gnp" checkout ad16d393106b23b6289d0569beefb8e9b3bd3159 - - name: Install goreleaser-npm-publisher runtime dependencies - working-directory: ${{ runner.temp }}/gnp - # set --mode=skip-build to block third-party install/postinstall scripts - run: corepack yarn install --immutable --mode=skip-build - name: Publish npm packages - run: >- - node "$RUNNER_TEMP/gnp/dist/cli.cjs" publish - --name cli - --bin flagsmith - --prefix @flagsmith - --license MIT - --repository 'git+https://github.com/Flagsmith/flagsmith-cli.git' - --description 'The Flagsmith command-line interface' - --keywords flagsmith feature-flags cli - --files README.md LICENSE + continue-on-error: ${{ github.event_name == 'workflow_dispatch' }} + uses: evg4b/goreleaser-npm-publisher-action@16087d5aafd974ba267f861cc3723f52ea14d6e4 # v1.6.0 + with: + name: cli + bin: flagsmith + prefix: "@flagsmith" + license: MIT + repository: ${{ github.repository }} + description: The Flagsmith command-line interface + keywords: |- + flagsmith + feature-flags + cli + files: |- + README.md + LICENSE - install-script: - name: install.sh (${{ matrix.os }}) + install-script-e2e: + name: install (${{ matrix.os }}, ${{ matrix.ref && 'tag' || 'head' }}) needs: goreleaser - if: github.event_name == 'push' strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest] + os: [ubuntu-latest, macos-latest, windows-latest] + # When release is dispatched, test both pinned and latest installers. + # For a normal (tag-pushed) release, test only latest installer. + ref: ${{ fromJSON(inputs.tag && format('["", "refs/tags/{0}"]', inputs.tag) || '[""]') }} runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: + ref: ${{ matrix.ref }} persist-credentials: false - - run: sh install.sh --version "$GITHUB_REF_NAME" --bin-dir "$RUNNER_TEMP/bin" - - run: flagsmith --version - - install-script-windows: - name: install.ps1 - needs: goreleaser - if: github.event_name == 'push' - runs-on: windows-latest - steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - persist-credentials: false - - run: ./install.ps1 -Version $env:GITHUB_REF_NAME + - name: Install latest (Linux) + if: ${{ !inputs.tag && runner.os != 'Windows' }} + run: sh install.sh + - name: Install dispatched (Linux) + if: ${{ inputs.tag && runner.os != 'Windows' }} + run: sh install.sh --version "${{ inputs.tag }}" + - name: Install latest (Windows) + if: ${{ !inputs.tag && runner.os == 'Windows' }} + run: ./install.ps1 shell: pwsh - - run: flagsmith --version + - name: Install dispatched (Windows) + if: ${{ inputs.tag && runner.os == 'Windows' }} + run: ./install.ps1 -Version "${{ inputs.tag }}" shell: pwsh + - run: flagsmith --version diff --git a/.goreleaser.yaml b/.goreleaser.yaml index e2f7817..1230880 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -89,3 +89,4 @@ changelog: release: mode: keep-existing prerelease: auto + replace_existing_artifacts: true