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
11 changes: 10 additions & 1 deletion .github/workflows/fleet-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@ name: fleet-lint
on:
push:
branches: [main]
# `edited` joins the three default types because pr-title reads the title out
# of the event payload: without it, a title corrected in response to the
# check raises no event, and a re-run replays the payload that failed. The
# only way left to clear the gate would be another push, which a title fix
# does not have.
pull_request:
types: [opened, synchronize, reopened, edited]
# Periodic coverage: these tools grow rules between releases, so a repository
# nobody has touched can start failing for a reason worth knowing about.
schedule:
Expand Down Expand Up @@ -209,7 +215,10 @@ jobs:
# drives the compiler over the whole workspace, and a pull request that
# touches no Rust cannot change what it would say.
needs: changes
if: needs.changes.outputs.rust == 'true'
# Not on an edited title or body: nothing a description says changes what
# the compiler sees, and this is the one job here that can run half an
# hour. The rest are seconds and can afford to answer every event.
if: needs.changes.outputs.rust == 'true' && github.event.action != 'edited'
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
# Whether hawk applies is answered on the runner, after checkout: a
Expand Down
14 changes: 11 additions & 3 deletions .vale.ini
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@
# clichés, redundancy — without imposing a voice on repositories whose readers
# are each other. A style guide can come later, from writing that exists.
StylesPath = .vale/styles
MinAlertLevel = warning

# Errors only. The action runs reviewdog with fail-on-error, which fails a job on
# any annotation it posts — warnings included — so a level reported is a level
# enforced, whatever the rule's own severity says. Reporting errors alone is what
# makes the levelling below mean anything. Lower this locally to read the advice.
MinAlertLevel = error

Packages = proselint, write-good

Expand All @@ -20,8 +25,11 @@ BasedOnStyles = proselint, write-good
write-good.ThereIs = warning
write-good.So = warning

# Prose lives in sentences; a fenced block is code someone will run.
BlockIgnores = (?s) *(```.*?```)
# Prose lives in sentences; a fenced block is code someone will run. Anchored to
# line starts because the unanchored form silently matched nothing: a fence with
# no language tag was graded as prose, and `[PATHS]...` in a usage block read as
# an ellipsis waiting to be typeset.
BlockIgnores = (?sm)^ *```.*?^ *```

# `vale sync` writes the style packages here, README files and all, and Vale
# then grades the prose of the linters it just downloaded.
Expand Down
30 changes: 21 additions & 9 deletions scripts/publish.sh
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
#!/usr/bin/env bash
# Publish jawohl to crates.io.
#
# Fleet-managed by conf (.ordnung/managed/publishing/rust/publish.sh): edit it
# there. The crate name is substituted from the repository name, so a crate
# named differently from its repository needs a copy of its own.
#
# Publishing is irreversible: a version can be yanked but never deleted, and a
# name/version pair can never be reused. The shape of this script follows from
# that.
#
# - Dry run is the default. Uploading takes --execute.
# - A version the registry already has is skipped rather than attempted, so
# re-running a release for an existing tag is a no-op instead of a failure.
# - An upload of a version the registry already has is skipped rather than
# attempted, so re-running a release for an existing tag is a no-op instead
# of a failure. A dry run is never skipped: it packages and compiles every
# time, because a publish check that returns success without building
# anything is exactly the green light nobody should trust.
# - Existing versions are read from the sparse index rather than the web API,
# because the index is what cargo itself resolves against, and because
# --index lets the whole path be rehearsed against a local registry.
Expand All @@ -31,10 +38,6 @@
# CARGO_REGISTRIES_<NAME>_TOKEN ... or for --execute --registry <name>.
# Neither is ever logged.
#
# Fleet-managed by conf (.ordnung/managed/publishing/rust/publish.sh): edit it
# there. The crate name is substituted from the repository name, so a crate
# named differently from its repository needs a copy of its own.
#
# straitjacket-allow-file:no-comments — this is the procedure for the one
# action in the repository that cannot be undone, and sh has no
# documentation-comment syntax to hoist the reasoning into.
Expand All @@ -54,7 +57,10 @@ while [ $# -gt 0 ]; do
--registry) REGISTRY=${2:?--registry needs a name}; shift ;;
--index) INDEX_BASE=${2:?--index needs a url or directory}; shift ;;
--allow-dirty) ALLOW_DIRTY=1 ;;
-h|--help) sed -n '2,33p' "${BASH_SOURCE[0]}"; exit 0 ;;
# The header is the help text, read rather than duplicated, so the two
# cannot drift. It stops at the suppression marker below it, which is
# addressed to the linter rather than to anyone running --help.
-h|--help) awk 'NR>1 && /straitjacket-allow-file/ {exit} NR>1 && /^#/ {print; next} NR>1 {exit}' "${BASH_SOURCE[0]}"; exit 0 ;;
-*) echo "publish: unknown flag $1" >&2; exit 2 ;;
*) echo "publish: unexpected argument $1" >&2; exit 2 ;;
esac
Expand Down Expand Up @@ -121,8 +127,14 @@ already_published() {
grep -q "\"vers\"[[:space:]]*:[[:space:]]*\"${VERSION}\"" <<<"$body"
}

if already_published; then
echo "publish: ${CRATE} ${VERSION} is already on the registry; nothing to do"
# Only --execute is skipped for a version the registry already has: that upload
# can never succeed and re-running a release for an existing tag should be a
# no-op rather than a failure. A dry run still packages and compiles, because a
# publish check that returns success without building anything is exactly the
# green light nobody should trust -- and on every commit that does not bump the
# version, that is every run.
if [ "$MODE" = execute ] && already_published; then
echo "publish: ${CRATE} ${VERSION} is already on the registry; nothing to upload"
exit 0
fi

Expand Down