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
91 changes: 18 additions & 73 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -1,87 +1,32 @@
# Sends bolt to the public Bend hub, and only when a person asks for it.
#
# This is the one workflow in the repo that uploads anything. The upload is
# public and cannot be taken back, so nothing triggers it but a human on
# Actions -> Publish -> Run workflow. There is no `push:` here and there never
# will be: release-please opens the GitHub Release, and this workflow does not
# run on a tag, so a tag that turns out to be wrong costs a deleted release
# and not a package on the hub forever.
#
# What it publishes is a tag, never a branch and never a loose commit. The
# `ref` is `refs/tags/<tag>`, so a branch name or a SHA does not resolve and
# the checkout fails before a hub is ever named. What the hub holds should be
# a thing that has a name in this repo's history.
#
# The upload itself is `ez publish` (ez/pub/pub.bend), the same ez the gate is:
# - it refuses on a dirty tree, untracked non-ignored files included, before
# it speaks to anything. A fresh checkout is clean, so this only fires when
# a step above has written into the tree -- which is the moment you want it
# to fire, since the package's file set is read off the working tree.
# - the `0x` name it reports is the one ez computed from that file set.
# bend's own output is checked against it, not grepped for it: bend 2.0.21
# prints three lines and two of them carry a `0x` name mid-line, so the
# first thing that looks like a hash is the wrong answer. A disagreement,
# or an output ez cannot read, stops the command and reports no name.
# That is the whole of the 122 lines of bash this replaces, and it is tested
# in ez's own gate rather than here.
#
# The gate runs here too, before the upload: see the step comment below.
#
# ez is checked out beside bolt and built with the `bend` this repo pins.
# There is no published ez release to fetch.

name: publish

# Publish an existing release tag to the Bend hub as bolt@X.Y.Z.0 by hand,
# e.g. to retry a release whose automatic publish failed. Releases are
# published automatically by release-please.yml. dry-run runs every check
# (proof gate, LICENSE, the hub's name check) and stops before the upload.

on:
workflow_dispatch:
inputs:
tag:
description: "The existing tag to publish, e.g. v0.4.0"
description: "The existing tag to publish, e.g. v1.2.0"
required: true
type: string

# one upload at a time: two of these racing would mine two proofs of work for
# the same package and tell you about it twice
concurrency:
group: publish
cancel-in-progress: false
dry-run:
description: "Check everything, upload nothing"
required: false
type: boolean
default: false

permissions:
contents: read

jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: refs/tags/${{ inputs.tag }}
path: bolt
- uses: actions/checkout@v4
with:
repository: Emerging-Patterns/ez
path: ez
- uses: DeterminateSystems/nix-installer-action@v23
- name: Build ez
working-directory: bolt
run: nix develop -c env BEND_LIB=../ez/.ez/lib bend ../ez/ez/main.bend -o ../ez.bin
# the gate, before the upload and not after it. A tag can be cut from
# anywhere, and what reaches the hub cannot be taken back: a bolt that
# fails its own tests is exactly what must not become a permanent
# package. `bend --publish` would catch a bolt that does not check,
# and nothing else.
- name: ez test
working-directory: bolt
run: nix develop -c env BEND_LIB=.ez/lib ../ez.bin fetch && nix develop -c ../ez.bin test
- name: ez publish
working-directory: bolt
shell: bash
# the tag reaches bash as an environment variable, never as `${{ }}`
# spliced into the script: an input is a string a person typed, and
# one interpolated into a `run:` block runs as shell.
env:
TAG: ${{ inputs.tag }}
run: |
nix develop -c ../ez.bin publish | tee "$RUNNER_TEMP/published"
{ echo "### bolt $TAG is on the hub"; echo; echo '```';
cat "$RUNNER_TEMP/published"; echo '```'; } >> "$GITHUB_STEP_SUMMARY"
uses: Emerging-Patterns/actions/.github/workflows/publish.yml@0fb03f81b72096c8db54be388d09ef5ab75fed3f
with:
tag: ${{ inputs.tag }}
hub-name: bolt
dry-run: ${{ inputs.dry-run }}
secrets:
bend-key: ${{ secrets.BEND_HUB_KEY }}
21 changes: 20 additions & 1 deletion .github/workflows/release-please.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
name: release-please

# release-please opens the release PR from conventional commits; merging it
# tags vX.Y.Z and creates the GitHub release. The publish job then sends that
# tag to the Bend hub as bolt@X.Y.Z.0: the shared publish workflow runs the
# proof gate and refuses a package with no LICENSE beside its entry before it
# uploads, since an upload is public and permanent. BEND_HUB_KEY is the Bender
# login of the account that owns the hub name.

on:
push:
branches: [main]
Expand All @@ -15,7 +22,19 @@ jobs:
contents: write
pull-requests: write
issues: write
uses: Emerging-Patterns/actions/.github/workflows/release-please.yml@a7b5322fe88c4974e06405cdf33b1aa00aa8d92a
uses: Emerging-Patterns/actions/.github/workflows/release-please.yml@0fb03f81b72096c8db54be388d09ef5ab75fed3f
with:
config-file: .github/release-please-config.json
manifest-file: .github/release-please-manifest.json

publish:
needs: release-please
if: needs.release-please.outputs.release_created == 'true'
permissions:
contents: read
uses: Emerging-Patterns/actions/.github/workflows/publish.yml@0fb03f81b72096c8db54be388d09ef5ab75fed3f
with:
tag: ${{ needs.release-please.outputs.tag_name }}
hub-name: bolt
secrets:
bend-key: ${{ secrets.BEND_HUB_KEY }}
Loading