Skip to content

ci: use Node 24 artifact uploader #976

ci: use Node 24 artifact uploader

ci: use Node 24 artifact uploader #976

Workflow file for this run

name: CI
on:
push: {}
pull_request:
branches: [main]
concurrency:
group: ci-${{ github.ref }}
# A newer main push must not cancel an older run once that run can enter publication. Branch and
# pull-request runs still supersede older work for the same ref.
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
permissions:
contents: read
env:
NODE_VERSION: "22.23.1"
NPM_VERSION: "10.9.8"
HAXE_VERSION: "4.3.7"
jobs:
security:
name: Locked dependency + secret audit
runs-on: ubuntu-24.04
timeout-minutes: 10
permissions:
contents: read
steps:
- name: Checkout full history for secret scanning
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- name: Setup exact Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: ${{ env.NODE_VERSION }}
- name: Observe affected-test recommendation without changing CI coverage
env:
BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.before }}
run: node scripts/ci/change-impact-selector.js --base "$BASE_SHA" --head "$GITHUB_SHA"
- name: Setup exact Ruby and RubyGems for advisory scanning
uses: ruby/setup-ruby@a30dfa457ad68707b8b910ac3a244714b61c0626 # v1.320.0
with:
ruby-version: "3.4.10"
rubygems: "3.6.9"
bundler: none
- name: Audit locked Node and Ruby dependencies
run: |
set -euo pipefail
test "$(node --version)" = "v${NODE_VERSION}"
test "$(npm --version)" = "${NPM_VERSION}"
test "$(ruby --disable-gems -e 'print RUBY_VERSION')" = "3.4.10"
test "$(gem --version)" = "3.6.9"
npm ci --ignore-scripts --no-audit --no-fund
npm audit
gem install bundler-audit --version 0.9.3 --no-document
npm run security:ruby-advisories
- name: Scan full Git history for secrets
uses: gitleaks/gitleaks-action@e0c47f4f8be36e29cdc102c57e68cb5cbf0e8d1e # v3
env:
GITHUB_TOKEN: ${{ github.token }}
haxe-format:
name: Haxe formatter
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: ${{ env.NODE_VERSION }}
- name: Install npm dependencies
run: npm ci --ignore-scripts --no-audit --no-fund
- name: Install Haxe (pinned via lix)
run: |
set -euo pipefail
npx lix download
npx lix download haxe "${{ env.HAXE_VERSION }}"
npx lix use haxe "${{ env.HAXE_VERSION }}"
echo "$(pwd)/node_modules/.bin" >> "$GITHUB_PATH"
export PATH="$(pwd)/node_modules/.bin:$PATH"
haxe -version
- name: Install Haxe formatter
run: haxelib install formatter --quiet
- name: Check Haxe formatting
run: npm run format:haxe:check
node-compatibility:
name: Node.js compatibility / ${{ matrix.node_version }}
runs-on: ubuntu-24.04
timeout-minutes: 10
strategy:
fail-fast: false
matrix:
node_version: ["22.14.0", "22.23.1"]
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: ${{ matrix.node_version }}
- name: Verify Node.js and npm compatibility
run: |
set -euo pipefail
test "$(node --version)" = "v${{ matrix.node_version }}"
case "${{ matrix.node_version }}" in
22.14.0) test "$(npm --version)" = "10.9.2" ;;
22.23.1) test "$(npm --version)" = "10.9.8" ;;
*) exit 1 ;;
esac
npm ci --ignore-scripts --no-audit --no-fund
npm run ci:support-matrix
npm run ci:version-sync
npm run test:release-version-policy
npm run test:release-workflow
npm run test:release-hosting
test:
name: Ruby ${{ matrix.ruby_version }} / Haxe 4.3.7
runs-on: ubuntu-24.04
# This lane runs the full compiler, RailsHx, generator, snapshot, and package
# suite across Ruby versions. Keep the cap above normal runtime so GitHub
# does not cancel healthy runs while late snapshot/package checks are active.
timeout-minutes: 45
strategy:
fail-fast: false
matrix:
ruby_version: ["3.3", "3.4", "4.0"]
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: ${{ env.NODE_VERSION }}
- name: Setup Ruby
uses: ruby/setup-ruby@a30dfa457ad68707b8b910ac3a244714b61c0626 # v1.320.0
with:
ruby-version: ${{ matrix.ruby_version }}
- name: Install npm dependencies
run: npm ci --ignore-scripts --no-audit --no-fund
- name: Install Haxe (pinned via lix)
run: |
set -euo pipefail
npx lix download
npx lix download haxe "${{ env.HAXE_VERSION }}"
npx lix use haxe "${{ env.HAXE_VERSION }}"
echo "$(pwd)/node_modules/.bin" >> "$GITHUB_PATH"
export PATH="$(pwd)/node_modules/.bin:$PATH"
haxe -version
- name: Run full test suite
run: npm test
rails-browser:
name: RailsHx browser sentinel
runs-on: ubuntu-24.04
timeout-minutes: 20
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: ${{ env.NODE_VERSION }}
- name: Setup Ruby
uses: ruby/setup-ruby@a30dfa457ad68707b8b910ac3a244714b61c0626 # v1.320.0
with:
ruby-version: "3.3"
- name: Install npm dependencies
run: npm ci --ignore-scripts --no-audit --no-fund
- name: Install Haxe (pinned via lix)
run: |
set -euo pipefail
npx lix download
npx lix download haxe "${{ env.HAXE_VERSION }}"
npx lix use haxe "${{ env.HAXE_VERSION }}"
echo "$(pwd)/node_modules/.bin" >> "$GITHUB_PATH"
export PATH="$(pwd)/node_modules/.bin:$PATH"
haxe -version
- name: Install Playwright Chromium
run: ./node_modules/.bin/playwright install --with-deps chromium
- name: Run RailsHx Playwright sentinel
run: npm run test:todoapp-playwright
rails-runtime:
name: RailsHx runtime integration / Ruby ${{ matrix.ruby_version }}
runs-on: ubuntu-24.04
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
ruby_version: ["3.3", "3.4", "4.0"]
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: ${{ env.NODE_VERSION }}
- name: Setup Ruby
uses: ruby/setup-ruby@a30dfa457ad68707b8b910ac3a244714b61c0626 # v1.320.0
with:
ruby-version: ${{ matrix.ruby_version }}
- name: Install npm dependencies
run: npm ci --ignore-scripts --no-audit --no-fund
- name: Install Haxe (pinned via lix)
run: |
set -euo pipefail
npx lix download
npx lix download haxe "${{ env.HAXE_VERSION }}"
npx lix use haxe "${{ env.HAXE_VERSION }}"
echo "$(pwd)/node_modules/.bin" >> "$GITHUB_PATH"
export PATH="$(pwd)/node_modules/.bin:$PATH"
haxe -version
- name: Run mandatory Rails runtime lanes
run: npm run test:rails-runtime
rails-production:
name: RailsHx production dogfood
runs-on: ubuntu-24.04
timeout-minutes: 25
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: ${{ env.NODE_VERSION }}
- name: Setup Ruby
uses: ruby/setup-ruby@a30dfa457ad68707b8b910ac3a244714b61c0626 # v1.320.0
with:
ruby-version: "3.3"
- name: Install npm dependencies
run: npm ci --ignore-scripts --no-audit --no-fund
- name: Install Haxe (pinned via lix)
run: |
set -euo pipefail
npx lix download
npx lix download haxe "${{ env.HAXE_VERSION }}"
npx lix use haxe "${{ env.HAXE_VERSION }}"
echo "$(pwd)/node_modules/.bin" >> "$GITHUB_PATH"
export PATH="$(pwd)/node_modules/.bin:$PATH"
haxe -version
- name: Run RailsHx production dogfood
run: npm run test:todoapp-production
- name: Measure stable viability workloads
run: npm run benchmark:stable -- --require-rails
release-contracts:
name: Release contracts
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: ${{ env.NODE_VERSION }}
- name: Setup Ruby for public upgrade rehearsal
uses: ruby/setup-ruby@a30dfa457ad68707b8b910ac3a244714b61c0626 # v1.320.0
with:
ruby-version: "3.4.10"
rubygems: "3.6.9"
bundler: none
- name: Install npm dependencies
run: npm ci --ignore-scripts --no-audit --no-fund
- name: Install exact Haxe toolchain for artifact contracts
run: |
set -euo pipefail
# Haxe's install hook invokes `lix` by name, so the local binary must be visible
# to child processes before either download begins.
export PATH="$(pwd)/node_modules/.bin:$PATH"
echo "$(pwd)/node_modules/.bin" >> "$GITHUB_PATH"
./node_modules/.bin/lix download
./node_modules/.bin/lix download haxe "${HAXE_VERSION}"
./node_modules/.bin/lix use haxe "${HAXE_VERSION}"
test "$(haxe -version)" = "${HAXE_VERSION}"
- name: Check version and release metadata
run: |
node scripts/ci/version-sync-check.js
npm run test:release-version-policy
npm run ci:release-contracts
- name: Exercise public v0.4.0 upgrade and rollback
run: npm run test:public-upgrade
change-impact-observation:
name: Change-impact observation
needs:
- security
- haxe-format
- node-compatibility
- test
- rails-browser
- rails-runtime
- rails-production
- release-contracts
# Run even when a backstop fails so the advisory report can distinguish an
# omitted failure from an incomplete (cancelled/skipped) observation.
if: ${{ always() }}
runs-on: ubuntu-24.04
timeout-minutes: 5
permissions:
contents: read
steps:
- name: Checkout full history for change classification
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- name: Setup exact Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: ${{ env.NODE_VERSION }}
- name: Correlate recommendations with unchanged full backstops
env:
BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.before }}
CI_NEEDS_JSON: ${{ toJSON(needs) }}
run: node scripts/ci/change-impact-observation.js --base "$BASE_SHA" --head "$GITHUB_SHA"
- name: Retain the machine-readable observation for review
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: change-impact-observation-${{ github.run_id }}-${{ github.run_attempt }}
path: test/.generated/change-impact/observation.json
if-no-files-found: error
include-hidden-files: true
retention-days: 30
release:
name: Release exact CI-tested commit
needs:
- security
- haxe-format
- node-compatibility
- test
- rails-browser
- rails-runtime
- rails-production
- release-contracts
- change-impact-observation
# Referencing a status function disables GitHub's implicit success() filter. Every declared
# dependency is then checked explicitly, so skipped/missing/failed/cancelled lanes still fail
# closed while a scheduler-level aggregate status cannot silently skip an all-green release.
if: >-
${{
!cancelled()
&& github.event_name == 'push'
&& github.ref == 'refs/heads/main'
&& github.repository == 'fullofcaffeine/reflaxe.ruby'
&& needs.security.result == 'success'
&& needs.haxe-format.result == 'success'
&& needs.node-compatibility.result == 'success'
&& needs.test.result == 'success'
&& needs.rails-browser.result == 'success'
&& needs.rails-runtime.result == 'success'
&& needs.rails-production.result == 'success'
&& needs.release-contracts.result == 'success'
&& needs.change-impact-observation.result == 'success'
}}
runs-on: ubuntu-24.04
timeout-minutes: 30
permissions:
contents: write
concurrency:
# The repair-only workflow added by the hosted-verification slice must use this exact group.
group: release-${{ github.repository }}
cancel-in-progress: false
steps:
- name: Checkout exact tested commit with full history
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
ref: ${{ github.sha }}
- name: Setup exact Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: "22.23.1"
# setup-node v7 otherwise auto-enables npm caching when packageManager is declared.
package-manager-cache: false
- name: Setup exact Ruby and RubyGems
uses: ruby/setup-ruby@a30dfa457ad68707b8b910ac3a244714b61c0626 # v1.320.0
with:
ruby-version: "3.4.10"
rubygems: "3.6.9"
bundler: none
- name: Verify exact release toolchain
run: |
set -euo pipefail
test "$(node --version)" = "v22.23.1"
test "$(npm --version)" = "10.9.8"
test "$(ruby --disable-gems -e 'print RUBY_VERSION')" = "3.4.10"
test "$(gem --version)" = "3.6.9"
- name: Install and audit locked npm dependencies
run: |
set -euo pipefail
npm ci --ignore-scripts --no-audit --no-fund
npm audit
- name: Install exact Haxe toolchain
run: |
set -euo pipefail
# Haxe's install hook invokes `lix` by name, so the local binary must be visible
# to child processes before either download begins.
export PATH="$(pwd)/node_modules/.bin:$PATH"
echo "$(pwd)/node_modules/.bin" >> "$GITHUB_PATH"
./node_modules/.bin/lix download
./node_modules/.bin/lix download haxe "4.3.7"
./node_modules/.bin/lix use haxe "4.3.7"
test "$(haxe -version)" = "4.3.7"
- name: Prepare historical prerelease transition
run: node scripts/release/prepare-semver-transition.mjs
- name: Derive, package, tag, and publish the tested SHA
env:
GITHUB_TOKEN: ${{ github.token }}
GH_TOKEN: ${{ github.token }}
run: ./node_modules/.bin/semantic-release