Skip to content

ci(workflows): pin build container images #87

ci(workflows): pin build container images

ci(workflows): pin build container images #87

Workflow file for this run

name: "Node addon"
# Builds the napi-rs Node addon (secretspec.node) per platform and smoke tests
# it. On a version tag, publishes it to npm as per-platform optional packages
# (secretspec-<platform>, referenced via the main `secretspec` package's
# optionalDependencies) using @napi-rs/cli, authenticated via npm Trusted
# Publishing (OIDC) -- no NPM_TOKEN stored in CI.
#
# The Linux builds run inside manylinux_2_28 containers (AlmaLinux 8, glibc
# 2.28), so the published addon loads on any distro with glibc >= 2.28
# (RHEL 8/9, Amazon Linux 2023, Debian 10+, Ubuntu 18.10+). Building on the bare
# runner instead links the runner's glibc (2.39 on ubuntu-24.04), which broke
# RHEL 9-family distros (issue #136). A post-build step fails the job if the
# addon's glibc floor or NEEDED libraries regress.
on:
workflow_call:
inputs:
publish:
description: Publish the built packages to npm
required: false
type: boolean
default: false
workflow_dispatch:
inputs:
publish:
description: Publish the built packages to npm
required: false
type: boolean
default: false
push:
tags:
- v**
# PR runs are scoped to changes in the Node SDK or this workflow. Core
# resolver changes are verified on PRs by the devenv-based test.yml and
# sdks.yml; the full matrix here still runs on tags and manual dispatch.
pull_request:
paths:
- "secretspec-node/**"
- ".github/workflows/node-addon.yml"
- "scripts/sync-sdk-versions.sh"
jobs:
addon:
name: ${{ matrix.target }}
runs-on: ${{ matrix.runner }}
container: ${{ matrix.container || null }}
strategy:
fail-fast: false
matrix:
include:
# `platform` is napi-rs's platformArchABI naming (see
# secretspec-node/npm/<platform>/), used to name the artifact that
# feeds the publish job below.
- target: linux-x64
platform: linux-x64-gnu
runner: ubuntu-latest
container: quay.io/pypa/manylinux_2_28_x86_64:2026.08.05-1@sha256:e0b40ace8e818e96026eb47714b01998cbca022a6995797d0905474ce3e82ae8
- target: linux-arm64
platform: linux-arm64-gnu
runner: ubuntu-24.04-arm
container: quay.io/pypa/manylinux_2_28_aarch64:2026.08.05-1@sha256:f766b402889e40f439e7a3ee5788eef1aa3ef399d0110107d27419fa2ba9d905
- { target: darwin-arm64, platform: darwin-arm64, runner: macos-latest }
- { target: win32-x64, platform: win32-x64-msvc, runner: windows-latest }
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Sync SDK package versions
run: bash scripts/sync-sdk-versions.sh
- name: Install rustup (the manylinux container ships none)
if: matrix.container
run: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain none
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
- name: Install Rust (pinned by rust-toolchain.toml)
run: rustup toolchain install
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: "22"
- name: Install napi CLI
run: npm ci
working-directory: secretspec-node
- name: Build the addon and run the SDK tests
shell: bash
run: |
bash secretspec-node/scripts/build-addon.sh
( cd secretspec-node && node --test )
- name: Verify addon portability (glibc <= 2.28, no libdbus)
if: matrix.container
shell: bash
run: bash scripts/check-linux-portability.sh secretspec-node/secretspec.node
- name: Copy the addon to its platform-specific filename for publishing
shell: bash
run: cp secretspec-node/secretspec.node "secretspec-node/secretspec.${{ matrix.platform }}.node"
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: node-addon-${{ matrix.target }}
path: secretspec-node/secretspec.${{ matrix.platform }}.node
publish:
name: publish to npm
# Version tags publish automatically. A standalone manual run can opt in to
# re-publishing one SDK, while reusable pre-release runs always leave this off.
if: (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')) || inputs.publish
needs: [addon]
runs-on: ubuntu-latest
permissions:
id-token: write # npm Trusted Publishing (OIDC), no token needed
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Sync SDK package versions
run: bash scripts/sync-sdk-versions.sh
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: "22"
registry-url: "https://registry.npmjs.org"
- name: Upgrade npm (Trusted Publishing needs npm >= 11.5.1)
# Pin to 11.x: npm 12's in-place global self-install leaves libnpmpublish's
# bundled sigstore dependency missing, which breaks provenance publishing
# ("Cannot find module 'sigstore'"). 11.5.1+ satisfies Trusted Publishing.
run: npm install -g npm@^11.5.1
- name: Install napi CLI
run: npm ci
working-directory: secretspec-node
- name: Scaffold per-platform npm package dirs
run: node_modules/.bin/napi create-npm-dirs
working-directory: secretspec-node
- name: Download platform addons
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: node-addon-*
path: artifacts
merge-multiple: true
- name: Place each addon into its npm package dir
shell: bash
run: |
for f in artifacts/secretspec.*.node; do
platform="$(basename "$f" .node | sed 's/^secretspec\.//')"
cp "$f" "secretspec-node/npm/$platform/$(basename "$f")"
done
- name: Publish platform packages
# --tag-style npm: our tags are `vX.Y.Z`, not lerna's `pkg@X.Y.Z`.
# --no-gh-release: v-release.yml (cargo-dist) already creates the
# GitHub Release for this tag; a second one here would conflict.
working-directory: secretspec-node
run: node_modules/.bin/napi pre-publish --tag-style npm --no-gh-release
- name: Publish main package
working-directory: secretspec-node
run: npm publish