Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions .github/scripts/gem-build
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#! /usr/bin/env bash
#
# run as part of CI, or as part of the release pipeline with --release
#
RELEASE=false
if [[ "${1:-}" == "--release" ]] ; then
RELEASE=true
shift
fi

if [[ $# -lt 2 ]] ; then
echo "usage: $(basename $0) [--release] <output_dir> <platform>"
exit 1
fi

set -e -u

OUTPUT_DIR=$1
BUILD_NATIVE_GEM=$2

test -e /etc/os-release && cat /etc/os-release

set -x

bundle config set without development

if [[ "${RELEASE}" == "true" ]] ; then
bundle install --local || bundle install
else
bundle config set frozen false
bundle install --local || bundle install
bundle exec rake gemspec:fake-version
fi

if [[ "${BUILD_NATIVE_GEM}" == "ruby" ]] ; then
bundle exec rake build
else
bundle exec rake gem:${BUILD_NATIVE_GEM}:build
fi

./test/prism/packaging/test-gem-file-contents pkg/*.gem

mkdir -p ${OUTPUT_DIR}
cp -v pkg/*.gem ${OUTPUT_DIR}
ls -l ${OUTPUT_DIR}/*
25 changes: 25 additions & 0 deletions .github/scripts/gem-install-test
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#! /usr/bin/env sh
#
# run as part of CI
#
if [ $# -lt 1 ] ; then
echo "usage: $(basename $0) <gem-file>"
exit 1
fi

gemfile=$1
shift

test -e /etc/os-release && cat /etc/os-release

set -e -x -u

ls -l ${gemfile}
gem install --no-document ${gemfile}
gem list -d prism

bundle config set without development
bundle install --local || bundle install

rm -rf lib ext # ensure we don't use the local files
rake test
103 changes: 103 additions & 0 deletions .github/workflows/build-gems.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
name: Build gems
on:
workflow_call:
inputs:
release:
description: "Pass --release to .github/scripts/gem-build (skip timestamp version)"
type: boolean
default: false
artifact_prefix:
description: "Prefix for artifact names (e.g., 'release-v1.10.0-')"
type: string
default: ""
ref:
description: "Git ref to check out (e.g., a version tag). Defaults to the caller's ref."
type: string
default: ""

permissions:
contents: read

jobs:
build_source_gem:
name: "source gem"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ inputs.ref || github.ref }}
persist-credentials: false
- uses: ruby/setup-ruby@c4e5b1316158f92e3d49443a9d58b31d25ac0f8f # v1.306.0
with:
ruby-version: "3.4"
bundler-cache: true
- name: Build source gem
run: |
# shellcheck disable=SC2086 # RELEASE_FLAG intentionally word-splits (empty or "--release")
./.github/scripts/gem-build ${RELEASE_FLAG} gems ruby
env:
RELEASE_FLAG: ${{ inputs.release && '--release' || '' }}
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: "${{ inputs.artifact_prefix }}source-gem"
path: gems
retention-days: 1

build_native_setup:
name: "setup"
runs-on: ubuntu-latest
outputs:
rcd_image_version: ${{ steps.rcd_image_version.outputs.rcd_image_version }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ inputs.ref || github.ref }}
persist-credentials: false
- uses: ruby/setup-ruby@c4e5b1316158f92e3d49443a9d58b31d25ac0f8f # v1.306.0
with:
ruby-version: "3.4"
bundler-cache: true
- id: rcd_image_version
run: bundle exec ruby -e 'require "rake_compiler_dock"; puts "rcd_image_version=#{RakeCompilerDock::IMAGE_VERSION}"' >> "$GITHUB_OUTPUT"

build_native_gem:
needs: build_native_setup
name: "native gem ${{ matrix.platform }}"
strategy:
# CI runs want to surface every platform's failure (fail-fast: false);
# release runs should stop on first failure to avoid pushing a partial
# set of gems.
fail-fast: ${{ inputs.release }}
matrix:
platform:
- aarch64-linux-gnu
- aarch64-linux-musl
- aarch64-mingw-ucrt
- arm-linux-gnu
- arm-linux-musl
- arm64-darwin
- x64-mingw-ucrt
- x86_64-darwin
- x86_64-linux-gnu
- x86_64-linux-musl
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ inputs.ref || github.ref }}
persist-credentials: false
- name: Build native gem
run: |
# shellcheck disable=SC2086 # RELEASE_FLAG intentionally word-splits (empty or "--release")
docker run --rm -v "$PWD:/work" -w /work \
"ghcr.io/rake-compiler/rake-compiler-dock-image:${RCD_IMAGE_VERSION}-mri-${PLATFORM}" \
./.github/scripts/gem-build ${RELEASE_FLAG} gems "${PLATFORM}"
env:
RCD_IMAGE_VERSION: ${{ needs.build_native_setup.outputs.rcd_image_version }}
RELEASE_FLAG: ${{ inputs.release && '--release' || '' }}
PLATFORM: ${{ matrix.platform }}
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: "${{ inputs.artifact_prefix }}cruby-${{ matrix.platform }}-gem"
path: gems
retention-days: 1
76 changes: 0 additions & 76 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -272,82 +272,6 @@ jobs:
- name: Run Ruby tests with valgrind
run: bundle exec rake test:valgrind

gem-package:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: ruby/setup-ruby@v1
with:
ruby-version: head
bundler-cache: true
- run: bundle config --local frozen false
- run: bundle exec rake build:dev
- uses: actions/upload-artifact@v7
with:
name: gem-package
path: pkg
retention-days: 1

gem-install:
needs: ["gem-package"]
strategy:
fail-fast: false
matrix:
target:
- { ruby: "2.7", os: "ubuntu-latest", gemfile: "2.7" }
- { ruby: "3.0", os: "ubuntu-latest", gemfile: "3.0" }
- { ruby: "3.1", os: "ubuntu-latest", gemfile: "3.1" }
- { ruby: "3.2", os: "ubuntu-latest", gemfile: "3.2" }
- { ruby: "3.3", os: "ubuntu-latest", gemfile: "3.3" }
- { ruby: "3.4", os: "ubuntu-latest", gemfile: "3.4" }
- { ruby: "4.0", os: "ubuntu-latest", gemfile: "4.0" }
- { ruby: "head", os: "ubuntu-latest", gemfile: "4.1" }
- { ruby: "jruby", os: "ubuntu-latest", gemfile: ".." }
- { ruby: "truffleruby", os: "ubuntu-latest", gemfile: ".." }

- { ruby: "2.7", os: "macos-latest", gemfile: "2.7" }
- { ruby: "3.0", os: "macos-latest", gemfile: "3.0" }
- { ruby: "3.1", os: "macos-latest", gemfile: "3.1" }
- { ruby: "3.2", os: "macos-latest", gemfile: "3.2" }
- { ruby: "3.3", os: "macos-latest", gemfile: "3.3" }
- { ruby: "3.4", os: "macos-latest", gemfile: "3.4" }
- { ruby: "4.0", os: "macos-latest", gemfile: "4.0" }
- { ruby: "head", os: "macos-latest", gemfile: "4.1" }
- { ruby: "jruby", os: "macos-latest", gemfile: ".." }
- { ruby: "truffleruby", os: "macos-latest", gemfile: ".." }

- { ruby: "2.7", os: "windows-latest", gemfile: "2.7" }
- { ruby: "3.0", os: "windows-latest", gemfile: "3.0" }
- { ruby: "3.1", os: "windows-latest", gemfile: "3.1" }
- { ruby: "3.2", os: "windows-latest", gemfile: "3.2" }
- { ruby: "3.3", os: "windows-latest", gemfile: "3.3" }
- { ruby: "3.4", os: "windows-latest", gemfile: "3.4" }
- { ruby: "4.0", os: "windows-latest", gemfile: "4.0" }
- { ruby: "head", os: "windows-latest", gemfile: "4.1" }
- { ruby: "jruby", os: "windows-latest", gemfile: ".." }
env:
BUNDLE_GEMFILE: gemfiles/${{ matrix.target.gemfile }}/Gemfile
runs-on: ${{ matrix.target.os }}
steps:
- uses: actions/checkout@v6
- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.target.ruby }}
- uses: actions/download-artifact@v8
with:
name: gem-package
path: pkg
- run: |
gem install --local pkg/prism-*.gem
gem list -d prism
shell: bash
- name: Run tests
run: |
bundle install
rm -rf lib ext # ensure we don't use the local files
rake test
shell: bash

gcc-analyzer:
runs-on: ubuntu-latest
steps:
Expand Down
68 changes: 58 additions & 10 deletions .github/workflows/publish-gem.yml
Original file line number Diff line number Diff line change
@@ -1,39 +1,87 @@
name: Publish gem to rubygems.org
concurrency:
group: "release-${{ inputs.version_tag || github.ref }}"
cancel-in-progress: false

on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
version_tag:
description: "Version tag to release (e.g., v1.10.0)"
required: true
type: string

permissions:
contents: read

jobs:
build:
uses: ./.github/workflows/build-gems.yml
with:
release: true
artifact_prefix: "release-${{ inputs.version_tag || github.ref_name }}-"
ref: ${{ inputs.version_tag || github.ref }}

push:
name: "Push gems and create GitHub release"
needs: build
if: github.repository == 'ruby/prism'
runs-on: ubuntu-latest

environment:
name: rubygems.org
url: https://rubygems.org/gems/prism

permissions:
contents: write
id-token: write

contents: write # create/update GitHub releases and upload .gem assets
id-token: write # OIDC token for rubygems.org trusted publishing
steps:
- name: Harden Runner
uses: step-security/harden-runner@v2
uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
with:
egress-policy: audit

- uses: actions/checkout@v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ inputs.version_tag || github.ref }}
persist-credentials: false

- name: Set up Ruby
uses: ruby/setup-ruby@v1
uses: ruby/setup-ruby@c4e5b1316158f92e3d49443a9d58b31d25ac0f8f # v1.306.0 # zizmor: ignore[cache-poisoning] -- cache is for gem-push tooling only; release artifacts come from prior job's uploaded artifacts, not this Ruby env
with:
ruby-version: "3.4"
bundler-cache: true

- name: Publish to RubyGems
uses: rubygems/release-gem@v1
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: gems
pattern: "release-${{ inputs.version_tag || github.ref_name }}-*"
merge-multiple: true

- name: Print and record checksums
run: |
cd gems
sha256sum ./*.gem | tee CHECKSUMS.txt

- uses: rubygems/configure-rubygems-credentials@762a4b77c3300434bb57c7ce80b20e36231927aa # v2.0.0

# TODO: once RubyGems >= 4.1 is in setup-ruby, `gem push` will auto-attest (ruby/rubygems#9325).
- name: Push gems to RubyGems.org
run: |
for gem in gems/*.gem; do
echo "Pushing ${gem} ..."
gem push "${gem}" || echo "WARNING: Failed to push ${gem} (may already exist)"
done

- name: Create or update GitHub release
env:
GH_TOKEN: ${{ github.token }}
TAG: ${{ inputs.version_tag || github.ref_name }}
REPO: ${{ github.repository }}
run: |
if gh release view "$TAG" --repo "$REPO" >/dev/null 2>&1 ; then
gh release upload "$TAG" --repo "$REPO" --clobber gems/*.gem gems/CHECKSUMS.txt
else
gh release create "$TAG" --repo "$REPO" --title "$TAG" --generate-notes gems/*.gem gems/CHECKSUMS.txt
fi
Loading
Loading