Skip to content
Merged
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
6 changes: 3 additions & 3 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,17 @@ Cargo aliases live in `.cargo/config.toml` (`t`, `cl`, `l`/`lint`, …).

## Generated artifacts

Both are rendered from the CLI definition behind off-by-default features
Both are rendered from the CLI definition behind off-by-default features,
never hand-edited.

- **`runner.toml` JSON Schema** committed under `schemas/`:
- **`runner.toml` JSON Schema**, committed under `schemas/`:

```sh
just gen-schema # cargo schema --output schemas/runner.toml.schema.json
git diff --exit-code schemas/ # drift guard
```

- **Man pages** (`man`/`schema` features) generated at release time, not
- **Man pages** (`man`/`schema` features), generated at release time, not
committed:

```sh
Expand Down
30 changes: 15 additions & 15 deletions .github/scripts/npm.sh
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ cmd_derive() {
}

# Install the packed tarballs into a scratch project and execute every
# bin — runs on the exact bytes `npm publish` ships.
# bin. Runs on the exact bytes `npm publish` ships.
# Required env: RELEASE_TAG.
cmd_smoke() {
: "${RELEASE_TAG:?RELEASE_TAG required}"
Expand Down Expand Up @@ -87,7 +87,7 @@ cmd_smoke() {

local platform_dir="${scratch}/app/node_modules/${scope}/${host_pkg}"

# Raw binaries the files whose exec bits the artifact handoff used to drop.
# Raw binaries, the files whose exec bits the artifact handoff used to drop.
local raw_bins=("${platform_dir}/bin/"*) raw
if [[ "${#raw_bins[@]}" -eq 0 ]]; then
echo "error: no binaries under ${platform_dir}/bin/" >&2
Expand Down Expand Up @@ -120,12 +120,12 @@ cmd_smoke() {
# still treat it as untrusted: defense-in-depth against a tampered
# artifact at the cross-workflow handoff or a malicious tag committer.
# Three defenses run before npm is invoked:
# 1. Hardcoded allowlist of expected directory names a tampered
# 1. Hardcoded allowlist of expected directory names, a tampered
# artifact cannot smuggle extra package directories.
# 2. Each package.json's `name` field must equal the expected
# scope/key prevents republishing as an unexpected package.
# scope/key, which prevents republishing as an unexpected package.
# 3. Each package.json's `version` field must equal the version
# derived from the trigger tag (trusted metadata) prevents
# derived from the trigger tag (trusted metadata), which prevents
# stamping arbitrary versions onto allowed packages.
# Single source of truth: npm/targets.json. `experimental: true`
# packages may legitimately be missing because their build matrix uses
Expand Down Expand Up @@ -159,7 +159,7 @@ cmd_publish() {
EXPECTED_VERSION="${RELEASE_TAG#v}"

# Refuse to proceed if the artifact contains anything outside the
# allowlist that's either a misconfiguration or an attack.
# allowlist; that's either a misconfiguration or an attack.
local allowed_set=" ${FACADE} ${REQUIRED_PLATFORMS[*]} ${OPTIONAL_PLATFORMS[*]} "
local dir base
for dir in npm/dist/*/; do
Expand All @@ -170,7 +170,7 @@ cmd_publish() {
fi
done

# 0644 binaries EACCES at spawn fail loud before publishing.
# 0644 binaries EACCES at spawn, fail loud before publishing.
local platform bin
for platform in "${REQUIRED_PLATFORMS[@]}" "${OPTIONAL_PLATFORMS[@]}"; do
for bin in "npm/dist/${platform}/bin/"*; do
Expand Down Expand Up @@ -198,7 +198,7 @@ cmd_publish() {
# Tier-1/2 are always required: the artifact is built by release.yml's
# build-dist (where missing tier-1/2 tarballs already fail loud),
# so a missing dir here means the artifact was tampered with or the
# build silently dropped a target either case warrants a hard fail.
# build silently dropped a target; either case warrants a hard fail.
# Sub-packages first so the façade's optionalDependencies resolve on install.
for platform in "${REQUIRED_PLATFORMS[@]}"; do
publish_allowed "npm/dist/${platform}" "${SCOPE}/${platform}" true
Expand All @@ -207,7 +207,7 @@ cmd_publish() {
publish_allowed "npm/dist/${platform}" "${SCOPE}/${platform}" false
done

# Façade is mandatory either way no point publishing a half-empty
# Façade is mandatory either way, no point publishing a half-empty
# set of platform packages with no entry point.
publish_allowed "npm/dist/${FACADE}" "${FACADE}" true
}
Expand Down Expand Up @@ -263,7 +263,7 @@ publish_allowed() {
# optionalDependencies validation. The facade is the only package that
# legitimately ships optionalDependencies (one entry per built platform
# package, all pinned to EXPECTED_VERSION). Platform packages must have
# none a tampered platform package could otherwise smuggle attacker-
# none; a tampered platform package could otherwise smuggle attacker-
# controlled deps that npm would happily install transitively.
if [[ "${expected_name}" == "${FACADE}" ]]; then
local dep_name dep_version platform dep_entries expected_dep_set=" ${REQUIRED_PLATFORMS[*]} ${OPTIONAL_PLATFORMS[*]} "
Expand Down Expand Up @@ -306,7 +306,7 @@ publish_allowed() {
echo "package-url=https://npm.im/package/${actual_name}/v/${version}" >>"${GITHUB_OUTPUT}"
fi

# Skip if already published npm versions are immutable, so reruns
# Skip if already published; npm versions are immutable, so reruns
# after a partial publish would otherwise fail on the first
# sub-package that already published. Bound the probe at 120s so a
# hung registry can't stall the whole publish job. Non-timeout
Expand All @@ -325,7 +325,7 @@ publish_allowed() {

local args=(publish --registry "${REGISTRY}" --access public --tag "${DIST_TAG}" --ignore-scripts --provenance)
if [[ "${DRY_RUN}" == "true" ]]; then args+=(--dry-run); fi
echo "+ npx -y npm@latest ${args[*]} (cwd: ${dir})"
echo "+ npx -y npm@11 ${args[*]} (cwd: ${dir})"
# Tolerate the TOCTOU race between the npm view check above and
# this publish: if another actor publishes the same version in
# the gap, npm exits with EPUBLISHCONFLICT and we treat that as a
Expand All @@ -335,12 +335,12 @@ publish_allowed() {
# `output=$(cmd); status=$?` would exit on a failing cmd before
# status was captured, and `if ! output=$(cmd); then status=$?`
# captures the negation status (always 0), not npm's real exit
# code silently masking real publish failures.
# code, silently masking real publish failures.
local output status=0
output=$(cd "${dir}" && timeout 120s npx -y npm@latest "${args[@]}" 2>&1) || status=$?
output=$(cd "${dir}" && timeout 120s npx -y npm@11 "${args[@]}" 2>&1) || status=$?
if [[ "${status}" -eq 124 ]]; then
printf '%s\n' "${output}" >&2
echo "error: 'npx -y npm@latest publish' for ${actual_name}@${version} timed out after 120s" >&2
echo "error: 'npx -y npm@11 publish' for ${actual_name}@${version} timed out after 120s" >&2
return 1
fi
if [[ "${status}" -ne 0 ]]; then
Expand Down
10 changes: 5 additions & 5 deletions .github/scripts/release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ cmd_package_asset() {
for bin in runner run; do
src="${BIN_DIR}/${bin}"
if [[ ! -f "${src}" ]]; then
echo "error: ${src} not found build step did not produce ${bin}" >&2
echo "error: ${src} not found, build step did not produce ${bin}" >&2
exit 1
fi
cp "${src}" "${staging}/${bin}"
Expand Down Expand Up @@ -115,7 +115,7 @@ cmd_verify_asset() {
if [[ "${#missing[@]}" -gt 0 ]]; then
echo "error: build+upload for ${TARGET} reported success but these assets are not on release ${RELEASE_TAG}:" >&2
printf ' - %s\n' "${missing[@]}" >&2
echo "the build step produced no artifact inspect its log for a silent no-op." >&2
echo "the build step produced no artifact; inspect its log for a silent no-op." >&2
exit 1
fi

Expand Down Expand Up @@ -151,7 +151,7 @@ cmd_verify_checksums() {
local tarballs=(*.tar.gz)
local sums=(*.sha256)

# Every tarball needs a matching .sha256 and vice versa otherwise an
# Every tarball needs a matching .sha256 and vice versa; otherwise an
# unchecksummed binary could slip through to publish.
if [[ "${#tarballs[@]}" -eq 0 ]]; then
echo "error: no tarballs downloaded for ${RELEASE_TAG}" >&2
Expand All @@ -166,7 +166,7 @@ cmd_verify_checksums() {
fi
done

# Each .sha256 must reference a tarball matching its own basename
# Each .sha256 must reference a tarball matching its own basename,
# defends against a swapped reference leaving a tarball unchecked.
for s in "${sums[@]}"; do
inner=$(awk '{sub(/^\*/, "", $2); print $2}' "${s}")
Expand Down Expand Up @@ -199,7 +199,7 @@ cmd_build_npm_packages() {
[[ -d man ]] && man_arg=(--man-dir man)

# build-packages.ts is tier-aware: missing tier-3 (experimental)
# tarballs are skipped, missing tier-1/2 fail the job.
# tarballs are skipped; missing tier-1/2 fail the job.
node npm/scripts/build-packages.ts --version "${version}" "${man_arg[@]}"
}

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/npm-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ jobs:
platforms: ${{ steps.matrix.outputs.platforms }}
facade: ${{ steps.matrix.outputs.facade }}
steps:
# Sparse-checkout from default branch no tag-supplied code on disk.
# Sparse-checkout from default branch, no tag-supplied code on disk.
- uses: actions/checkout@v7
with:
ref: ${{ github.event.repository.default_branch }}
Expand Down Expand Up @@ -78,7 +78,7 @@ jobs:
echo "error: no run-id resolvable for ${RELEASE_TAG}" >&2
exit 1
fi
# Numeric guard blocks GITHUB_OUTPUT injection.
# Numeric guard, blocks GITHUB_OUTPUT injection.
if ! [[ "${run_id}" =~ ^[0-9]+$ ]]; then
echo "error: run-id '${run_id}' is not a positive integer" >&2
exit 1
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ jobs:
with: { sparse-checkout: npm/targets.json, sparse-checkout-cone-mode: false, persist-credentials: false }

- id: gen
# `target: .rust` is mandatory taiki-e and build-packages.ts both
# `target: .rust` is mandatory; taiki-e and build-packages.ts both
# derive the asset filename `runner-<tag>-<rust>.tar.gz` from it.
# `vm`-typed targets need a dedicated job; filtered out here.
run: |
Expand Down Expand Up @@ -215,7 +215,7 @@ jobs:
needs: [upload-assets, man]
runs-on: ubuntu-latest
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
permissions: { contents: write } # contents: write drafts are invisible to read-only tokens.
permissions: { contents: write } # contents: write, drafts are invisible to read-only tokens.
env: { RELEASE_TAG: "${{ github.ref_name }}" }
steps:
- uses: actions/checkout@v7
Expand Down
Loading