Skip to content

docs: reconcile repo hygiene checkpoint #81

docs: reconcile repo hygiene checkpoint

docs: reconcile repo hygiene checkpoint #81

Workflow file for this run

name: Release
on:
push:
branches:
- main
workflow_dispatch:
inputs:
recovery_reason:
description: "Exact-ref automation/recovery note for running the trusted release lane"
required: true
type: string
recovery_ref:
description: "Commit SHA or tag for the exact revision being published or recovered"
required: true
type: string
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false
permissions:
contents: read
env:
ELIXIR_VERSION: "1.19.5"
OTP_VERSION: "28"
jobs:
release-please:
name: Release Please
runs-on: ubuntu-latest
permissions:
contents: write
issues: write
pull-requests: write
outputs:
release_created: ${{ steps.release.outputs.release_created || steps.manual_dispatch.outputs.release_created || 'false' }}
tag_name: ${{ steps.release.outputs.tag_name || '' }}
release_sha: ${{ steps.release.outputs.sha || '' }}
steps:
- name: Check out repository for Release Please
if: ${{ github.event_name != 'workflow_dispatch' }}
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Confirm dispatch stays exact-ref only
id: manual_dispatch
if: ${{ github.event_name == 'workflow_dispatch' }}
shell: bash
run: |
echo "release_created=false" >> "$GITHUB_OUTPUT"
echo "workflow_dispatch bypasses Release Please and exists only to run the trusted publish lane for an exact immutable ref selected by release automation or recovery."
- name: Record review-only Release Please PR posture
if: ${{ github.event_name != 'workflow_dispatch' }}
run: |
echo "Release Please generated PRs are review-only. Checked-in version and changelog truth becomes authoritative only after the merged release commit crosses the protected hex-publish environment."
echo "Push-triggered Release Please manages release PRs only; the exact-ref dispatch publish lane owns GitHub release/tag creation and Hex publish for the root lockspire-v<version> contract."
- name: Run Release Please
id: release
if: ${{ github.event_name != 'workflow_dispatch' }}
uses: ./.github/actions/release-please
with:
config-file: release-please-config.json
manifest-file: .release-please-manifest.json
skip-github-release: true
- name: Record root release tag target for the merged release commit
if: ${{ github.event_name != 'workflow_dispatch' && steps.release.outputs.release_created == 'true' && steps.release.outputs.sha == github.sha }}
run: |
echo "Release Please selected root tag ${{ steps.release.outputs.tag_name }} for the merged release commit. Protected publish proof begins only when the publish job enters the hex-publish environment on main."
- name: Record stale Release Please release event
if: ${{ github.event_name != 'workflow_dispatch' && steps.release.outputs.release_created == 'true' && steps.release.outputs.sha != github.sha }}
run: |
echo "Release Please created or finalized ${{ steps.release.outputs.tag_name }} for ${{ steps.release.outputs.sha }}, but this workflow is running for ${{ github.sha }}."
echo "Skipping publish on this push prevents republishing an existing Hex package after a delayed Release Please tagging event."
recovery-validation:
name: Validate Recovery Ref
if: ${{ github.event_name == 'workflow_dispatch' }}
runs-on: ubuntu-latest
permissions:
contents: read
outputs:
checkout_ref: ${{ steps.validate.outputs.checkout_ref }}
steps:
- name: Check out repository for recovery validation
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
fetch-tags: true
- name: Validate exact-ref dispatch inputs and lock to an immutable ref
id: validate
shell: bash
run: |
set -euo pipefail
test -n "${{ inputs.recovery_reason }}"
recovery_ref="${{ inputs.recovery_ref }}"
test -n "$recovery_ref"
if [[ "$recovery_ref" =~ ^[0-9a-f]{40}$ ]]; then
git cat-file -e "${recovery_ref}^{commit}"
echo "checkout_ref=$recovery_ref" >> "$GITHUB_OUTPUT"
elif git show-ref --verify --quiet "refs/tags/$recovery_ref"; then
echo "checkout_ref=$recovery_ref" >> "$GITHUB_OUTPUT"
else
echo "workflow_dispatch is exact-ref only and recovery_ref must be an exact 40-character commit SHA or an existing tag."
exit 1
fi
echo "workflow_dispatch is exact-ref only. It publishes the exact immutable ref selected in recovery_ref, and normal release intent still starts from a merged Release Please commit in the protected hex-publish environment."
publish:
name: Publish to Hex
runs-on: ubuntu-latest
needs:
- release-please
- recovery-validation
if: ${{ always() && ((github.event_name == 'workflow_dispatch' && needs.recovery-validation.result == 'success') || (github.event_name != 'workflow_dispatch' && needs.release-please.outputs.release_created == 'true' && needs.release-please.outputs.release_sha == github.sha)) }}
environment: hex-publish
permissions:
contents: write
steps:
- name: Check out repository for the merged release commit
if: ${{ github.event_name != 'workflow_dispatch' }}
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Check out repository for recovery validation
if: ${{ github.event_name == 'workflow_dispatch' }}
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
fetch-tags: true
ref: ${{ needs.recovery-validation.outputs.checkout_ref }}
- name: Confirm recovery checkout is detached to the validated immutable ref
if: ${{ github.event_name == 'workflow_dispatch' }}
shell: bash
run: |
set -euo pipefail
git checkout --detach HEAD
echo "Recovered immutable ref: ${{ needs.recovery-validation.outputs.checkout_ref }}"
- name: Record protected-boundary entry point
shell: bash
run: |
set -euo pipefail
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
echo "Protected publish proof starts now for dispatch ref ${{ needs.recovery-validation.outputs.checkout_ref }} inside the single hex-publish environment boundary."
else
echo "Protected publish proof starts now for merged release tag ${{ needs.release-please.outputs.tag_name }} inside the single hex-publish environment boundary."
fi
- name: Ensure dispatch GitHub release exists
if: ${{ github.event_name == 'workflow_dispatch' }}
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
shell: bash
run: |
set -euo pipefail
version="$(grep -E '^[[:space:]]*version:' mix.exs | head -1 | sed -E 's/.*"([^"]+)".*/\1/')"
tag_name="lockspire-v${version}"
release_title="lockspire: v${version}"
if gh release view "$tag_name" >/dev/null 2>&1; then
echo "GitHub release $tag_name already exists."
exit 0
fi
notes="$(
awk -v version="$version" '
$0 ~ "^## \\[" version "\\]" { in_section = 1; next }
in_section && $0 ~ "^## \\[" { exit }
in_section { print }
' CHANGELOG.md
)"
test -n "$notes"
gh release create "$tag_name" \
--target "$(git rev-parse HEAD)" \
--title "$release_title" \
--notes "$notes"
- name: Set up Elixir and Erlang
uses: erlef/setup-beam@fc68ffb90438ef2936bbb3251622353b3dcb2f93 # v1.24.0
with:
elixir-version: ${{ env.ELIXIR_VERSION }}
otp-version: ${{ env.OTP_VERSION }}
- name: Install Hex and Rebar
run: |
mix local.hex --force
mix local.rebar --force
- name: Restore Mix cache
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: |
deps
_build
key: ${{ runner.os }}-mix-release-v2-${{ env.OTP_VERSION }}-${{ env.ELIXIR_VERSION }}-${{ hashFiles('mix.lock') }}
restore-keys: |
${{ runner.os }}-mix-release-v2-${{ env.OTP_VERSION }}-${{ env.ELIXIR_VERSION }}-
- name: Install dependencies
run: mix deps.get
- name: Run trusted release preflight inside protected environment
env:
HEX_API_KEY: ${{ secrets.HEX_API_KEY }}
run: mix release.preflight
- name: Publish package from the trusted lane
env:
HEX_API_KEY: ${{ secrets.HEX_API_KEY }}
run: mix hex.publish --yes