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
271 changes: 267 additions & 4 deletions .github/workflows/lastcode-intel-artifact.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,55 @@ on:
permissions:
contents: read

concurrency:
group: lastcode-intel-artifact-${{ inputs.installable_tag }}
cancel-in-progress: false

jobs:
build:
name: Validate and build macOS x64
runs-on: macos-15-intel
timeout-minutes: 90
outputs:
needs_build: ${{ steps.release.outputs.needs_build }}
version: ${{ steps.target.outputs.version }}
env:
INSTALLABLE_TAG: ${{ inputs.installable_tag }}
INSTALLABLE_COMMIT: ${{ inputs.installable_commit }}
steps:
- name: Checkout workflow automation
uses: actions/checkout@v6
Comment thread
lastobelus marked this conversation as resolved.
Resolved
with:
fetch-depth: 1
path: automation
persist-credentials: false
ref: ${{ github.workflow_sha }}
sparse-checkout: |
/package.json
/scripts/lastcode-intel-release.mjs
sparse-checkout-cone-mode: false

- name: Setup Node for release validation
uses: actions/setup-node@v6
with:
node-version-file: automation/package.json

- name: Require immutable GitHub Releases
working-directory: automation
env:
GH_TOKEN: ${{ github.token }}
run: |
gh api -H "X-GitHub-Api-Version: 2026-03-10" \
"repos/${GITHUB_REPOSITORY}/immutable-releases" > "$RUNNER_TEMP/immutable-releases.json"
node scripts/lastcode-intel-release.mjs validate-repository \
--repository-json "$RUNNER_TEMP/immutable-releases.json"

- name: Checkout exact installable
uses: actions/checkout@v6
with:
fetch-depth: 0
path: target
persist-credentials: false
ref: ${{ inputs.installable_commit }}
Comment thread
lastobelus marked this conversation as resolved.
Resolved
sparse-checkout: |
/*
Expand All @@ -37,6 +73,7 @@ jobs:
- name: Validate immutable tag and commit
id: target
shell: bash
working-directory: target
run: |
set -euo pipefail

Expand Down Expand Up @@ -64,26 +101,84 @@ jobs:
version="${version#lastcode/revision/v}"
echo "version=$version" >> "$GITHUB_OUTPUT"

- name: Reuse a validated exact-tag release
id: release
shell: bash
working-directory: automation
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail

encoded_tag="${INSTALLABLE_TAG//\//%2F}"
set +e
probe="$(
gh api --include --silent \
"repos/${GITHUB_REPOSITORY}/releases/tags/${encoded_tag}" 2>&1
)"
probe_exit=$?
set -e
http_status="$(
printf '%s\n' "$probe" |
awk '$1 ~ /^HTTP\// { status = $2 } END { print status }'
)"

if [[ "$http_status" == "404" ]]; then
echo "needs_build=true" >> "$GITHUB_OUTPUT"
exit 0
fi
if [[ "$probe_exit" -ne 0 || "$http_status" != "200" ]]; then
printf '%s\n' "$probe" >&2
echo "Could not determine whether the exact-tag release exists." >&2
exit 1
fi

release_dir="$RUNNER_TEMP/existing-intel-release"
release_json="$RUNNER_TEMP/existing-intel-release.json"
mkdir -p "$release_dir"
gh release view "$INSTALLABLE_TAG" \
--repo "$GITHUB_REPOSITORY" \
--json assets,isDraft,isImmutable,isPrerelease,tagName > "$release_json"
gh release download "$INSTALLABLE_TAG" \
--repo "$GITHUB_REPOSITORY" \
--dir "$release_dir"
node scripts/lastcode-intel-release.mjs validate \
--directory "$release_dir" \
--tag "$INSTALLABLE_TAG" \
--commit "$INSTALLABLE_COMMIT" \
--release-json "$release_json"
echo "Exact-tag Intel release is already complete; skipping CI and packaging."
echo "needs_build=false" >> "$GITHUB_OUTPUT"

- name: Setup Vite+
if: steps.release.outputs.needs_build == 'true'
uses: voidzero-dev/setup-vp@v1
with:
working-directory: target
node-version-file: package.json
cache: true
run-install: true

- name: Setup Rust x64 target
if: steps.release.outputs.needs_build == 'true'
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
targets: x86_64-apple-darwin

- name: Install mobile CI prerequisites
if: steps.release.outputs.needs_build == 'true'
working-directory: target
run: brew bundle install --file apps/mobile/Brewfile

- name: Run full checkpoint gate
if: steps.release.outputs.needs_build == 'true'
working-directory: target
run: env -u ELECTRON_RUN_AS_NODE node scripts/lastcode-local-ci.ts --full --checkpoint "$INSTALLABLE_TAG"

- name: Build certificate-free x64 DMG
if: steps.release.outputs.needs_build == 'true'
working-directory: target
env:
CSC_IDENTITY_AUTO_DISCOVERY: "false"
GIT_COMMITTER_EMAIL: 41898282+github-actions[bot]@users.noreply.github.com
Expand All @@ -96,10 +191,178 @@ jobs:
--output-root release-lastcode
--verbose

- name: Upload exact-tag artifact for inspection
- name: Validate built exact-tag assets
id: artifact
if: steps.release.outputs.needs_build == 'true'
shell: bash
working-directory: target
run: |
set -euo pipefail

short_commit="$(git rev-parse --short=10 "$INSTALLABLE_COMMIT")"
artifact_dir="release-lastcode/v${{ steps.target.outputs.version }}/${short_commit}"
node "$GITHUB_WORKSPACE/automation/scripts/lastcode-intel-release.mjs" validate \
--directory "$artifact_dir" \
--tag "$INSTALLABLE_TAG" \
--commit "$INSTALLABLE_COMMIT"
echo "directory=$artifact_dir" >> "$GITHUB_OUTPUT"

- name: Transfer validated assets to publisher
if: steps.release.outputs.needs_build == 'true'
uses: actions/upload-artifact@v7
with:
name: lastcode-macos-x64-${{ steps.target.outputs.version }}
path: release-lastcode/v${{ steps.target.outputs.version }}/**
name: intel-release
path: target/${{ steps.artifact.outputs.directory }}/*
if-no-files-found: error
retention-days: 14
retention-days: 1

publish:
name: Publish immutable exact-tag assets
needs: build
if: needs.build.outputs.needs_build == 'true'
runs-on: ubuntu-24.04
timeout-minutes: 15
permissions:
contents: write
env:
INSTALLABLE_TAG: ${{ inputs.installable_tag }}
INSTALLABLE_COMMIT: ${{ inputs.installable_commit }}
steps:
- name: Checkout workflow automation
uses: actions/checkout@v6
with:
fetch-depth: 1
persist-credentials: false
ref: ${{ github.workflow_sha }}
sparse-checkout: |
/package.json
/scripts/lastcode-intel-release.mjs
sparse-checkout-cone-mode: false

- name: Setup Node for release validation
uses: actions/setup-node@v6
with:
node-version-file: package.json

- name: Require immutable GitHub Releases
env:
GH_TOKEN: ${{ github.token }}
run: |
gh api -H "X-GitHub-Api-Version: 2026-03-10" \
"repos/${GITHUB_REPOSITORY}/immutable-releases" > "$RUNNER_TEMP/immutable-releases.json"
node scripts/lastcode-intel-release.mjs validate-repository \
--repository-json "$RUNNER_TEMP/immutable-releases.json"

- name: Download isolated build assets
uses: actions/download-artifact@v8
with:
name: intel-release
path: release

- name: Validate isolated build assets
run: >-
node scripts/lastcode-intel-release.mjs validate
--directory release
--tag "$INSTALLABLE_TAG"
--commit "$INSTALLABLE_COMMIT"

- name: Reuse a release created during the build
id: release
shell: bash
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail

encoded_tag="${INSTALLABLE_TAG//\//%2F}"
set +e
probe="$(
gh api --include --silent \
"repos/${GITHUB_REPOSITORY}/releases/tags/${encoded_tag}" 2>&1
)"
probe_exit=$?
set -e
http_status="$(
printf '%s\n' "$probe" |
awk '$1 ~ /^HTTP\// { status = $2 } END { print status }'
)"

if [[ "$http_status" == "404" ]]; then
echo "needs_publish=true" >> "$GITHUB_OUTPUT"
exit 0
fi
if [[ "$probe_exit" -ne 0 || "$http_status" != "200" ]]; then
printf '%s\n' "$probe" >&2
echo "Could not determine whether the exact-tag release exists." >&2
exit 1
fi

release_dir="$RUNNER_TEMP/existing-intel-release"
release_json="$RUNNER_TEMP/existing-intel-release.json"
mkdir -p "$release_dir"
gh release view "$INSTALLABLE_TAG" \
--repo "$GITHUB_REPOSITORY" \
--json assets,isDraft,isImmutable,isPrerelease,tagName > "$release_json"
gh release download "$INSTALLABLE_TAG" \
--repo "$GITHUB_REPOSITORY" \
--dir "$release_dir"
node scripts/lastcode-intel-release.mjs validate \
--directory "$release_dir" \
--tag "$INSTALLABLE_TAG" \
--commit "$INSTALLABLE_COMMIT" \
--release-json "$release_json"
echo "Exact-tag Intel release was completed during the build; skipping publication."
echo "needs_publish=false" >> "$GITHUB_OUTPUT"

- name: Revalidate immutable tag before publication
if: steps.release.outputs.needs_publish == 'true'
shell: bash
run: |
set -euo pipefail

git fetch --force --no-tags origin \
"refs/tags/${INSTALLABLE_TAG}:refs/tags/${INSTALLABLE_TAG}"
publish_commit="$(git rev-parse "${INSTALLABLE_TAG}^{commit}")"
if [[ "$publish_commit" != "$INSTALLABLE_COMMIT" ]]; then
echo "Tag moved during the build: expected $INSTALLABLE_COMMIT, resolved $publish_commit" >&2
exit 1
fi

- name: Publish and verify exact-tag assets
if: steps.release.outputs.needs_publish == 'true'
shell: bash
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail

gh api -H "X-GitHub-Api-Version: 2026-03-10" \
"repos/${GITHUB_REPOSITORY}/immutable-releases" > "$RUNNER_TEMP/immutable-releases.json"
node scripts/lastcode-intel-release.mjs validate-repository \
--repository-json "$RUNNER_TEMP/immutable-releases.json"

release_notes="$(printf '%s\n%s\n' \
"Certificate-free LastCode macOS x64 artifacts for ${INSTALLABLE_TAG}." \
"Exact commit: ${INSTALLABLE_COMMIT}")"
gh release create "$INSTALLABLE_TAG" release/* \
Comment thread
lastobelus marked this conversation as resolved.
Resolved
--repo "$GITHUB_REPOSITORY" \
--verify-tag \
--prerelease \
--latest=false \
--title "LastCode Intel ${{ needs.build.outputs.version }}" \
--notes "$release_notes"

verify_dir="$RUNNER_TEMP/published-intel-release"
release_json="$RUNNER_TEMP/published-intel-release.json"
mkdir -p "$verify_dir"
gh release view "$INSTALLABLE_TAG" \
--repo "$GITHUB_REPOSITORY" \
--json assets,isDraft,isImmutable,isPrerelease,tagName > "$release_json"
gh release download "$INSTALLABLE_TAG" \
--repo "$GITHUB_REPOSITORY" \
--dir "$verify_dir"
node scripts/lastcode-intel-release.mjs validate \
--directory "$verify_dir" \
--tag "$INSTALLABLE_TAG" \
--commit "$INSTALLABLE_COMMIT" \
--release-json "$release_json"
5 changes: 4 additions & 1 deletion docs/lastcode/nightly-workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -376,10 +376,13 @@ only when that build record should be published to the fork.

Configure the fork so that:

- immutable releases are enabled under repository **Settings → Releases**;
- checkpoint, revision, and build tags cannot be modified or deleted;
- only the owner or automation identity can force-push `lastcode/main`;
- ordinary LastCode changes arrive through PRs targeting `lastcode/main`; and
- GitHub Actions remain disabled while local CI is authoritative.
- GitHub Actions are enabled only for the manually dispatched
[LastCode Intel artifact workflow](release.md#intel-build-publication), while
ordinary CI remains disabled because local CI is authoritative.

Branch protection must permit the intentional force-with-lease promotion model.
If GitHub cannot express that narrowly enough for a personal repository, rely on
Expand Down
Loading