Skip to content

Merge pull request #637 from codeslash-dev/claude/root-alias-token-re… #472

Merge pull request #637 from codeslash-dev/claude/root-alias-token-re…

Merge pull request #637 from codeslash-dev/claude/root-alias-token-re… #472

Workflow file for this run

name: Publish dist branch
# Builds the CSS bundles after every merge to main and force-pushes the
# resulting dist/ tree to a dedicated `dist` branch. The `dist` branch is
# orphan (no shared history with main) and contains only the generated
# bundles at its root, so consumers can reference them via:
#
# https://cdn.jsdelivr.net/gh/codeslash-dev/SLASHED@dist/slashed.optimal.min.css
#
# Source files (core/, optional/, etc.) live only on main; built files live
# only on dist. This keeps main free of generated artifacts while still
# giving the CDN something to serve.
on:
push:
branches: [main]
workflow_dispatch:
inputs:
git_ref:
description: 'Exact git SHA or ref to build from (leave blank to use HEAD of the triggered ref)'
required: false
default: ''
# Skip only commits that explicitly opt out via [skip ci] in the message.
# The version-sync commit pushed by release.yml deliberately does NOT carry
# that tag, so a version bump always rebuilds the dist branch with the correct
# header.
# If several merges land in quick succession, cancel any in-flight publish
# and rerun against the newest commit only. Prevents racing force-pushes.
concurrency:
group: publish-dist
cancel-in-progress: true
permissions:
contents: write
jobs:
publish-dist:
name: Build and force-push dist branch
runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, '[skip ci]')"
steps:
- name: Checkout main
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 1
# Don't write GITHUB_TOKEN into .git/config; the build steps
# (npm install, npm run build) shouldn't have implicit push
# credentials. We re-authenticate explicitly at push time below.
persist-credentials: false
# When dispatched from release.yml, git_ref is the exact post-sync SHA
# so the dist bundles are always stamped with the released version.
ref: ${{ inputs.git_ref || github.sha }}
# Resolve the SHA that was actually checked out. When dispatched with a
# custom git_ref, GITHUB_SHA still points at the dispatch trigger commit,
# not the built tree — use this for provenance stamping instead.
- name: Resolve checked-out source SHA
id: source
run: echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
# No dependency cache on the publish path: a poisoned cache could be
# baked into the dist bundles served from the CDN. Fetch fresh from the
# registry with integrity verification (zizmor: cache-poisoning).
- name: Setup Node
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 22
- name: Install dependencies
run: npm ci
- name: Build dist bundles
run: npm run build
- name: Stage dist for orphan branch
run: |
set -euo pipefail
mkdir -p /tmp/sf-dist
# CSS bundles + css-custom-data.json live in dist/; the shields.io
# badge endpoints (badge-*.json) live in badges/. Both must coexist at
# the published `dist` branch root, so merge them here at publish time.
cp -R dist/. /tmp/sf-dist/
cp badges/*.json /tmp/sf-dist/
# Ship the machine-readable API index alongside the bundles so
# integrations can fetch it from the same CDN path, e.g.:
# https://cdn.jsdelivr.net/gh/codeslash-dev/SLASHED@dist/api-index.json
cp docs/api-index.json /tmp/sf-dist/api-index.json
# Stamp file so consumers can verify exactly which source commit
# produced this dist tree.
{
echo "source-commit: ${{ steps.source.outputs.sha }}"
echo "source-ref: ${GITHUB_REF}"
echo "built-at: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
echo "built-by: .github/workflows/publish-dist.yml"
} > /tmp/sf-dist/SOURCE.txt
# git rm -rf . (below) deletes .gitignore from the working tree, which
# would cause `git add -A` to stage node_modules/ (134 MB). Ship a
# minimal .gitignore on the dist branch to prevent that.
echo 'node_modules/' > /tmp/sf-dist/.gitignore
- name: Force-push dist branch
env:
# Scoped to this step only — checkout was started with
# persist-credentials: false, so GITHUB_TOKEN never landed in
# .git/config and never leaked into the build/install steps.
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GIT_AUTHOR_NAME: github-actions[bot]
GIT_AUTHOR_EMAIL: 41898282+github-actions[bot]@users.noreply.github.com
GIT_COMMITTER_NAME: github-actions[bot]
GIT_COMMITTER_EMAIL: 41898282+github-actions[bot]@users.noreply.github.com
run: |
set -euo pipefail
git checkout --orphan dist
# The orphan checkout still stages main's tree; remove it all so
# only built artifacts end up on the dist branch.
git rm -rf . > /dev/null
shopt -s dotglob
cp -R /tmp/sf-dist/. .
git add -A
git commit -m "build: dist for ${{ steps.source.outputs.sha }}"
git push --force \
"https://x-access-token:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" \
dist