Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add release workflow for trusted gem publishing #597

Merged
merged 13 commits into from
Aug 28, 2024
175 changes: 175 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
# See GH-544 for detail
name: 🚀
on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+.*'
branches:
- main
paths:
- '.github/workflows/release.yml'
- 'lib/**'
- '**.gemspec'
- 'Gemfile'
- 'Rakefile'
- '.ruby-version'
pull_request:
paths:
- '.github/workflows/release.yml'
- 'lib/**'
- '**.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.isnpect.outputs.checksum_file }}
prerelease: ${{ steps.isnpect.outputs.prerelease }}
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" | tee --append "$GITHUB_OUTPUT"
echo "package_name=$package_name" | tee --append "$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 }}' | 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"
else
echo 'prerelease=false' >> "$GITHUB_OUTPUT"
fi
- 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
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 - 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
- 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:
GH_TOKEN: ${{ github.token }}
# 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
run: |
gem install 'release-assets/${{ needs.build.outputs.gem_file }}'
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]
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 release-assets
- name: Wait other jobs
uses: kachick/[email protected]
timeout-minutes: 10
with:
skip-same-workflow: 'true'
skip-list: |
[
{
"workflowFile": "merge-bot-pr.yml"
}
]
- name: Publish as a prerelease version
# 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 == 'false' }}
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 release-assets
- name: Configure trusted publishing credentials
uses: rubygems/configure-rubygems-credentials@bc6dd217f8a4f919d6835fcfefd470ef821f5c44 # v1.0.0
- name: Wait other jobs
uses: kachick/[email protected]
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 }}'
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,7 @@ benchmark/compare_with_othergems/*/vendor/
.DS_Store

.tool-versions

# Unpacked gem directory
/ruby-ulid-*/
/release-assets/