From 1330f7241030d841ae703c801f4b880b993531e3 Mon Sep 17 00:00:00 2001 From: Kenichi Kamiya Date: Wed, 28 Aug 2024 18:02:46 +0900 Subject: [PATCH 01/13] Add release workflow for trusted gem publishing --- .github/workflows/release.yml | 157 ++++++++++++++++++++++++++++++++++ .gitignore | 4 + 2 files changed, 161 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..b2f07f5a --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,157 @@ +# See GH-544 for detail +name: 🚀 +on: + push: + tags: + - 'v[0-9]+.[0-9]+.[0-9]+.*' + branches: + - main + paths: + - '.github/workflows/release.yml' + - 'lib/**' + - 'test/**' + - 'spec/**' + - '.rspec' + - '**.gemspec' + - 'Gemfile' + - 'Rakefile' + - '.ruby-version' + pull_request: + paths: + - '.github/workflows/release.yml' + - 'lib/**' + - 'test/**' + - 'spec/**' + - '.rspec' + - '**.gemspec' + - 'Gemfile' + - 'Rakefile' + - '.ruby-version' + workflow_dispatch: +jobs: + build: + timeout-minutes: 15 + runs-on: 'ubuntu-24.04' + env: + # https://github.com/kachick/ruby-ulid/blob/104834846baf5caa1e8536a11c43acdd56fc849c/CONTRIBUTING.md#adding-dependencies-for-this-gem + BUNDLE_WITHOUT: development + outputs: + gem_file: ${{ steps.build.outputs.built_file }} + checksum_file: ${{ steps.build.outputs.checksum_file }} + steps: + - uses: actions/checkout@v4 + - uses: ruby/setup-ruby@a6e6f86333f0a2523ece813039b8b4be04560854 # v1.190.0 + with: + # Enabling is the recommended way, but it cannot detect runner changes in early stage. + # So disable it is better for test job, do not mind in other jobs + bundler-cache: false # runs 'bundle install' and caches installed gems automatically + - run: bundle install + - name: Build + id: build + run: | + built_file="$(bundle exec rake validate_gem | ruby -e 'puts STDIN.read.slice(/\bFile: (ruby-ulid-\S+?\.gem)$/, 1)')" + package_name="$(basename --suffix '.gem' "$built_file")" + echo "built_file=$built_file" > "$GITHUB_OUTPUT" + echo "package_name=$package_name" > "$GITHUB_OUTPUT" + - name: Inspect + id: isnpect + run: | + gem install '${{ steps.build.outputs.built_file }}' + gem unpack '${{ steps.build.outputs.built_file }}' + tree '${{ steps.build.outputs.package_name }}' + checksum_file="${{ steps.build.outputs.package_name }}._checksums.txt" + sha256sum '${{ steps.build.outputs.built_file }}' > "$checksum_file" + echo "checksum_file=$checksum_file" > "$GITHUB_OUTPUT" + - name: Upload the gem file as an artifact + uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6 + with: + name: 'release-assets' + path: | + ${{ steps.build.outputs.built_file }} + ${{ steps.isnpect.outputs.checksum_file }} + check-installability: + needs: [build] + timeout-minutes: 15 + runs-on: 'ubuntu-24.04' + steps: + # Required to checkout for gh command + - uses: actions/checkout@v4 + - uses: ruby/setup-ruby@a6e6f86333f0a2523ece813039b8b4be04560854 # v1.190.0 + with: + bundler-cache: false + - name: Download release-assets + env: + GH_TOKEN: ${{ github.token }} + run: | + gh run download + tree + - name: Make sure we can use the gem + run: | + gem install 'release-assets/${{ needs.build.outputs.gem_file }}' + ruby -r 'ulid' -e 'pp [ULID.generate, ULID.sample(3)]' + github: + if: startsWith(github.ref, 'refs/tags/') + needs: [build, check-installability] + timeout-minutes: 15 + runs-on: 'ubuntu-24.04' + env: + GH_TOKEN: ${{ github.token }} + steps: + # Required to checkout for gh command + - uses: actions/checkout@v4 + - name: Download release-assets + run: | + gh run download + tree + - name: Wait other jobs + uses: kachick/wait-other-jobs@v3.4.0 + timeout-minutes: 10 + with: + skip-same-workflow: 'true' + skip-list: | + [ + { + "workflowFile": "merge-bot-pr.yml" + } + ] + - name: Publish + run: | + gh release create --verify-tag "$GITHUB_REF_NAME" --title "$GITHUB_REF_NAME" release-assets/* + rubygems: + if: startsWith(github.ref, 'refs/tags/') + needs: [build, check-installability, github] + timeout-minutes: 15 + runs-on: 'ubuntu-24.04' + permissions: + id-token: write # IMPORTANT: this permission is mandatory for trusted publishing + steps: + # Required to checkout for gh command + - uses: actions/checkout@v4 + - uses: ruby/setup-ruby@a6e6f86333f0a2523ece813039b8b4be04560854 # v1.190.0 + with: + bundler-cache: false + - name: Download release-assets + env: + GH_TOKEN: ${{ github.token }} + run: | + gh run download + tree + - name: Configure trusted publishing credentials + uses: rubygems/configure-rubygems-credentials@bc6dd217f8a4f919d6835fcfefd470ef821f5c44 # v1.0.0 + - name: Wait other jobs + uses: kachick/wait-other-jobs@v3.4.0 + timeout-minutes: 10 + with: + skip-same-workflow: 'true' + skip-list: | + [ + { + "workflowFile": "merge-bot-pr.yml" + } + ] + - name: Publish + run: | + gem push 'release-assets/${{ needs.build.outputs.gem_file }}' + - name: Wait for release to propagate + run: | + gem exec rubygems-await 'release-assets/${{ needs.build.outputs.gem_file }}' diff --git a/.gitignore b/.gitignore index f70acf09..1eb5cb92 100644 --- a/.gitignore +++ b/.gitignore @@ -66,3 +66,7 @@ benchmark/compare_with_othergems/*/vendor/ .DS_Store .tool-versions + +# Unpacked gem directory +/ruby-ulid-*/ +/release-assets/ From 98acee8fccffdfff1dc3576397d3ce0b1814181a Mon Sep 17 00:00:00 2001 From: Kenichi Kamiya Date: Wed, 28 Aug 2024 18:06:09 +0900 Subject: [PATCH 02/13] Fix overriding and prefer tee to debug --- .github/workflows/release.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b2f07f5a..4c7c4988 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -51,8 +51,8 @@ jobs: run: | built_file="$(bundle exec rake validate_gem | ruby -e 'puts STDIN.read.slice(/\bFile: (ruby-ulid-\S+?\.gem)$/, 1)')" package_name="$(basename --suffix '.gem' "$built_file")" - echo "built_file=$built_file" > "$GITHUB_OUTPUT" - echo "package_name=$package_name" > "$GITHUB_OUTPUT" + echo "built_file=$built_file" | tee --append "$GITHUB_OUTPUT" + echo "package_name=$package_name" | tee --append "$GITHUB_OUTPUT" - name: Inspect id: isnpect run: | @@ -61,7 +61,7 @@ jobs: tree '${{ steps.build.outputs.package_name }}' checksum_file="${{ steps.build.outputs.package_name }}._checksums.txt" sha256sum '${{ steps.build.outputs.built_file }}' > "$checksum_file" - echo "checksum_file=$checksum_file" > "$GITHUB_OUTPUT" + echo "checksum_file=$checksum_file" | tee --append "$GITHUB_OUTPUT" - name: Upload the gem file as an artifact uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6 with: From 91e9fff8eb4d06bc9cb3d5c420b320160483a2dc Mon Sep 17 00:00:00 2001 From: Kenichi Kamiya Date: Wed, 28 Aug 2024 18:07:47 +0900 Subject: [PATCH 03/13] Also prefer tee for checksum --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4c7c4988..718735e8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -60,7 +60,7 @@ jobs: gem unpack '${{ steps.build.outputs.built_file }}' tree '${{ steps.build.outputs.package_name }}' checksum_file="${{ steps.build.outputs.package_name }}._checksums.txt" - sha256sum '${{ steps.build.outputs.built_file }}' > "$checksum_file" + sha256sum '${{ steps.build.outputs.built_file }}' | tee --append "$checksum_file" echo "checksum_file=$checksum_file" | tee --append "$GITHUB_OUTPUT" - name: Upload the gem file as an artifact uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6 From 2a2a71c96553bbc05f7ab8dcfc5876ef80ec071d Mon Sep 17 00:00:00 2001 From: Kenichi Kamiya Date: Wed, 28 Aug 2024 18:09:00 +0900 Subject: [PATCH 04/13] Reduce needless display filetree --- .github/workflows/release.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 718735e8..2fa64b18 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -84,7 +84,7 @@ jobs: GH_TOKEN: ${{ github.token }} run: | gh run download - tree + tree release-assets - name: Make sure we can use the gem run: | gem install 'release-assets/${{ needs.build.outputs.gem_file }}' @@ -102,7 +102,7 @@ jobs: - name: Download release-assets run: | gh run download - tree + tree release-assets - name: Wait other jobs uses: kachick/wait-other-jobs@v3.4.0 timeout-minutes: 10 @@ -135,7 +135,7 @@ jobs: GH_TOKEN: ${{ github.token }} run: | gh run download - tree + tree release-assets - name: Configure trusted publishing credentials uses: rubygems/configure-rubygems-credentials@bc6dd217f8a4f919d6835fcfefd470ef821f5c44 # v1.0.0 - name: Wait other jobs From 058b12327a12091580b85ffd64f2c23b750424cb Mon Sep 17 00:00:00 2001 From: Kenichi Kamiya Date: Wed, 28 Aug 2024 18:18:46 +0900 Subject: [PATCH 05/13] Make robust CI for the least behaviors --- .github/workflows/release.yml | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2fa64b18..42187199 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -72,12 +72,23 @@ jobs: check-installability: needs: [build] timeout-minutes: 15 - runs-on: 'ubuntu-24.04' + strategy: + fail-fast: false + # Syntax https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs + matrix: + os: + - ubuntu-24.04 + - macos-14 # aarch64 + - macos-13 # x86_64 + # Due to https://github.com/actions/runner/issues/849, we have to use quotes for 'n.0' + ruby: ['head', '3.3', '3.2'] + runs-on: ${{ matrix.os }} steps: # Required to checkout for gh command - uses: actions/checkout@v4 - uses: ruby/setup-ruby@a6e6f86333f0a2523ece813039b8b4be04560854 # v1.190.0 with: + ruby-version: ${{ matrix.ruby }} bundler-cache: false - name: Download release-assets env: @@ -88,7 +99,7 @@ jobs: - name: Make sure we can use the gem run: | gem install 'release-assets/${{ needs.build.outputs.gem_file }}' - ruby -r 'ulid' -e 'pp [ULID.generate, ULID.sample(3)]' + ruby -r 'ulid' -e 'pp [ULID.generate, ULID.sample(3), ULID.parse(%q_01F4A5Y1YAQCYAYCTC7GRMJ9AA_)]' github: if: startsWith(github.ref, 'refs/tags/') needs: [build, check-installability] From 9c9f92cb063615fb90b932966c86259c184eecbc Mon Sep 17 00:00:00 2001 From: Kenichi Kamiya Date: Wed, 28 Aug 2024 18:21:46 +0900 Subject: [PATCH 06/13] Consider missing command in macos runner --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 42187199..9a45ab37 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -93,9 +93,9 @@ jobs: - name: Download release-assets env: GH_TOKEN: ${{ github.token }} + # Do not use tree and 'tee --append; for macos runner. Keep minimum run: | gh run download - tree release-assets - name: Make sure we can use the gem run: | gem install 'release-assets/${{ needs.build.outputs.gem_file }}' From 55b46ba239a0433faabcf2af6a2d5f7fbfed8557 Mon Sep 17 00:00:00 2001 From: Kenichi Kamiya Date: Wed, 28 Aug 2024 18:31:37 +0900 Subject: [PATCH 07/13] Fix getting checksum file path --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9a45ab37..b0b6f242 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -37,7 +37,7 @@ jobs: BUNDLE_WITHOUT: development outputs: gem_file: ${{ steps.build.outputs.built_file }} - checksum_file: ${{ steps.build.outputs.checksum_file }} + checksum_file: ${{ steps.isnpect.outputs.checksum_file }} steps: - uses: actions/checkout@v4 - uses: ruby/setup-ruby@a6e6f86333f0a2523ece813039b8b4be04560854 # v1.190.0 From 8d0a010e9c3785aa56306dd1d081b45be54d9518 Mon Sep 17 00:00:00 2001 From: Kenichi Kamiya Date: Wed, 28 Aug 2024 18:40:02 +0900 Subject: [PATCH 08/13] Mark prerelease if having suffix --- .github/workflows/release.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b0b6f242..17f69116 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -38,6 +38,7 @@ jobs: outputs: gem_file: ${{ steps.build.outputs.built_file }} checksum_file: ${{ steps.isnpect.outputs.checksum_file }} + prerelease: ${{ steps.isnpect.outputs.prerelease }} steps: - uses: actions/checkout@v4 - uses: ruby/setup-ruby@a6e6f86333f0a2523ece813039b8b4be04560854 # v1.190.0 @@ -62,6 +63,9 @@ jobs: checksum_file="${{ steps.build.outputs.package_name }}._checksums.txt" sha256sum '${{ steps.build.outputs.built_file }}' | tee --append "$checksum_file" echo "checksum_file=$checksum_file" | tee --append "$GITHUB_OUTPUT" + if [[ ${GITHUB_REF#refs/tags/} =~ ^v[0-9]+\.[0-9]+\.[0-9]+.+ ]]; then + echo 'prerelease=true' >> "$GITHUB_OUTPUT" + fi - name: Upload the gem file as an artifact uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6 with: @@ -125,7 +129,12 @@ jobs: "workflowFile": "merge-bot-pr.yml" } ] + - name: Publish as a prerelease version + if: needs.build.outputs.prerelease + run: | + gh release create --verify-tag "$GITHUB_REF_NAME" --title "$GITHUB_REF_NAME" --prerelease release-assets/* - name: Publish + if: ! needs.build.outputs.prerelease run: | gh release create --verify-tag "$GITHUB_REF_NAME" --title "$GITHUB_REF_NAME" release-assets/* rubygems: From 410440cf8047fd30ec26fdf21d79e4cafadb8f9a Mon Sep 17 00:00:00 2001 From: Kenichi Kamiya Date: Wed, 28 Aug 2024 18:46:50 +0900 Subject: [PATCH 09/13] Fix prerelease handler --- .github/workflows/release.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 17f69116..ce4eebec 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -65,6 +65,8 @@ jobs: echo "checksum_file=$checksum_file" | tee --append "$GITHUB_OUTPUT" if [[ ${GITHUB_REF#refs/tags/} =~ ^v[0-9]+\.[0-9]+\.[0-9]+.+ ]]; then echo 'prerelease=true' >> "$GITHUB_OUTPUT" + else + echo 'prerelease=false' >> "$GITHUB_OUTPUT" fi - name: Upload the gem file as an artifact uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6 @@ -130,11 +132,12 @@ jobs: } ] - name: Publish as a prerelease version - if: needs.build.outputs.prerelease + # To be strict, prefer `!= false` than `== true` + if: ${{ needs.build.outputs.prerelease != 'false' }} run: | gh release create --verify-tag "$GITHUB_REF_NAME" --title "$GITHUB_REF_NAME" --prerelease release-assets/* - name: Publish - if: ! needs.build.outputs.prerelease + if: ${{ needs.build.outputs.prerelease == 'false' }} run: | gh release create --verify-tag "$GITHUB_REF_NAME" --title "$GITHUB_REF_NAME" release-assets/* rubygems: From b0fc0ff99e1e420b98242218af99a2f91d041293 Mon Sep 17 00:00:00 2001 From: Kenichi Kamiya Date: Wed, 28 Aug 2024 18:48:48 +0900 Subject: [PATCH 10/13] Make sure we can install it in windows --- .github/workflows/release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ce4eebec..61786c84 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -86,6 +86,7 @@ jobs: - ubuntu-24.04 - macos-14 # aarch64 - macos-13 # x86_64 + - windows-2022 # Due to https://github.com/actions/runner/issues/849, we have to use quotes for 'n.0' ruby: ['head', '3.3', '3.2'] runs-on: ${{ matrix.os }} From a15a38f571c0038c94ba8039d6fa47b1d7c805eb Mon Sep 17 00:00:00 2001 From: Kenichi Kamiya Date: Wed, 28 Aug 2024 18:52:13 +0900 Subject: [PATCH 11/13] Update comment to follow windows runner --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 61786c84..3b14a5d8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -100,7 +100,7 @@ jobs: - name: Download release-assets env: GH_TOKEN: ${{ github.token }} - # Do not use tree and 'tee --append; for macos runner. Keep minimum + # Do not use tree and 'tee --append; for macos and windows runner. Keep minimum run: | gh run download - name: Make sure we can use the gem From b730575834f3e5e36956e4a7d10dc5b6298efb1a Mon Sep 17 00:00:00 2001 From: Kenichi Kamiya Date: Wed, 28 Aug 2024 18:53:48 +0900 Subject: [PATCH 12/13] Remove test files from release trigger --- .github/workflows/release.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3b14a5d8..cad534cf 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,9 +9,6 @@ on: paths: - '.github/workflows/release.yml' - 'lib/**' - - 'test/**' - - 'spec/**' - - '.rspec' - '**.gemspec' - 'Gemfile' - 'Rakefile' @@ -20,9 +17,6 @@ on: paths: - '.github/workflows/release.yml' - 'lib/**' - - 'test/**' - - 'spec/**' - - '.rspec' - '**.gemspec' - 'Gemfile' - 'Rakefile' From 45e7b78ece69e668ac5632308e1f78adfcc0d595 Mon Sep 17 00:00:00 2001 From: Kenichi Kamiya Date: Wed, 28 Aug 2024 18:57:36 +0900 Subject: [PATCH 13/13] Reduce matrix pattern for faster CI --- .github/workflows/release.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cad534cf..6c128735 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -79,10 +79,10 @@ jobs: os: - ubuntu-24.04 - macos-14 # aarch64 - - macos-13 # x86_64 - - windows-2022 - # Due to https://github.com/actions/runner/issues/849, we have to use quotes for 'n.0' - ruby: ['head', '3.3', '3.2'] + # - macos-13 # x86_64 - CPU arch does not affect for this gem (I think) + # - windows-2022 - Too slow. Please tell me if any Windows user is using this gem. + # For actual use-case, head is needless here + ruby: ['3.3', '3.2'] runs-on: ${{ matrix.os }} steps: # Required to checkout for gh command