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
19 changes: 4 additions & 15 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ name: Pages

# proc-cli.com: the Jekyll site in docs/, plus the signed apt repository at
# /apt, built from the .deb files of the last three releases that have them
# (pkg/apt/build-repo.sh). Runs on changes to the site, and from release.yml
# after each release, since a release made by the workflow's own token starts
# no other workflow.
# (pkg/apt/build-repo.sh). Runs on changes to the site, and after each release,
# whose update-apt job starts it on main's newest commit (release.yml says why
# that commit), since a release made by the workflow's own token starts no
# other workflow.
on:
push:
branches: [main]
Expand All @@ -13,10 +14,6 @@ on:
- 'pkg/apt/**'
- '.github/workflows/pages.yml'
workflow_dispatch:
workflow_call:
secrets:
APT_SIGNING_KEY:
required: false

permissions:
contents: read
Expand All @@ -31,14 +28,6 @@ concurrency:
jobs:
build:
name: Build site and apt repository
# A deploy is named after its commit, and Pages keeps the first deploy of a
# commit: the release commit's own push to main would deploy it before the
# release has its .deb files, and the release's deploy of the same commit
# would change nothing (2.3.0's apt repository stayed at 2.2.0). The release
# deploys that commit itself, from update-apt in release.yml.
if: >-
!(github.ref == 'refs/heads/main'
&& startsWith(github.event.head_commit.message, 'chore: release v'))
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
Expand Down
57 changes: 50 additions & 7 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -760,17 +760,60 @@ jobs:
git diff --staged --quiet || git commit -m "proc ${{ github.ref_name }}"
git push

# Pages keeps the first deploy of a commit and ignores the next, and nearly
# every push to main deploys (each change regenerates docs/changelog.md), so
# the tagged commit was deployed before the release had its .deb files: 2.4.0
# deployed it again here, and /apt stayed at 2.3.0. main's newest commit is
# the one commit-package-files pushed, which nothing has deployed (a push
# with this workflow's token starts no workflow), so pages.yml deploys that
update-apt:
name: Update the apt repository
needs: create-release
if: github.event_name == 'push'
needs: [create-release, commit-package-files]
if: ${{ !cancelled() && github.event_name == 'push' && needs.create-release.result == 'success' }}
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
actions: write
contents: read
pages: write
id-token: write
uses: ./.github/workflows/pages.yml
secrets:
APT_SIGNING_KEY: ${{ secrets.APT_SIGNING_KEY }}
steps:
- name: Deploy main's newest commit
env:
GH_TOKEN: ${{ github.token }}
run: |
head=$(gh api "repos/$GITHUB_REPOSITORY/commits/main" --jq .sha)
if [ "$head" = "$GITHUB_SHA" ]; then
echo "::error::main's newest commit is the tagged one, which Pages deployed before ${GITHUB_REF_NAME}'s packages existed (commit-package-files pushed nothing). After the next push to main, run: gh workflow run pages.yml --ref main"
exit 1
fi
gh workflow run pages.yml --repo "$GITHUB_REPOSITORY" --ref main
run=
for _ in $(seq 30); do
sleep 10
run=$(gh run list --repo "$GITHUB_REPOSITORY" --workflow pages.yml \
--event workflow_dispatch --commit "$head" --limit 1 \
--json databaseId --jq '.[0].databaseId // empty')
[ -n "$run" ] && break
done
[ -n "$run" ] || { echo "::error::no Pages run started for $head in 5 minutes"; exit 1; }
gh run watch "$run" --repo "$GITHUB_REPOSITORY" --exit-status --interval 15

# Pages serves with a 10-minute cache that a query string does not get
# past, so the check reads until the cached copy has expired
- name: Check that /apt lists the release
run: |
version=${GITHUB_REF_NAME#v}
for arch in amd64 arm64; do
url=https://proc-cli.com/apt/dists/stable/main/binary-$arch/Packages
for _ in $(seq 30); do
if curl -fsS "$url" | grep -qx "Version: $version"; then
echo "$url lists $version"
continue 2
fi
sleep 30
done
echo "::error::$url does not list $version after 15 minutes"
exit 1
done

update-winget:
name: Update winget
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

- **The apt repository gets the release's packages, and the release checks it.** 2.4.0's `/apt` kept listing 2.3.0 until it was redeployed by hand. Pages keeps the first deploy of a commit and ignores the next, and nearly every push to main deploys, so the tagged commit had been deployed before the release had its `.deb` files; the guard added in 2.3.0 skipped only a commit titled `chore: release v…`, and 2.4.0 tagged a later commit. `update-apt` now waits for "Commit the package files" and starts `pages.yml` on main's newest commit, which that job pushed and nothing has deployed, then reads `/apt`'s package lists for amd64 and arm64 until they show the release, and fails if they don't within 15 minutes. If no package commit was pushed, it fails at once and says how to deploy. `pages.yml` drops the guard and its `workflow_call` trigger. Nothing changed in proc

- **Two more tests no longer fail on timing.** `coloured_text_is_the_plain_text_plus_escape_codes` runs `proc list` with and without colour and compares the text. 2.4.0 made it rerun the pair until both printed the same cells, but on Windows CI 10 pairs in a row differed, the last on the listener's uptime (10s against 11s). Digits are now compared as digits, not as values, so a ticking figure matches; a figure that changes its width, or a cell that changes its word, still reruns the pair, and the spacing must still match. It still fails when colour changes the spacing (checked by planting a space in coloured cells). `a_process_records_its_parents_name_and_its_children` compared a `sleep`'s parent name with its shell's name from a later read of the process table. On macOS `sh` is a launcher that turns into `bash`, and under load one read could see the shell as `sh` and the `sleep` that `bash` started (the unit tests failed 4 of 8 runs on a Mac, 0 of 8 after); it now compares the two from the same read. Nothing changed in proc

## [2.4.0] - 2026-11-11
Expand Down
4 changes: 2 additions & 2 deletions RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ After tag push, monitor GitHub Actions:
- [ ] Homebrew tap updated
- [ ] Scoop bucket updated
- [ ] Docker image pushed
- [ ] "Update the apt repository" passed: https://proc-cli.com/apt/dists/stable/main/binary-amd64/Packages lists the new version. The release commit's own push to main deploys nothing (`pages.yml` skips a commit titled `chore: release v…`, since Pages keeps only the first deploy of a commit), so the site, the new version on it included, changes when this job deploys
- [ ] "Update the apt repository" passed: https://proc-cli.com/apt/dists/stable/main/binary-amd64/Packages lists the new version; the job checks it itself, for amd64 and arm64, and fails if it doesn't. Pages keeps only the first deploy of a commit, and the tagged commit was deployed by its own push, before the release had its `.deb` files, so the job deploys main's newest commit instead: the one "Commit the package files" pushed. If that job pushed nothing, this one fails and says so: deploy after the next push to main with `gh workflow run pages.yml --ref main`
- [ ] "Update winget" opened the pull request for the new version on microsoft/winget-pkgs (until the first version is merged it skips, with a notice). The day the first version (2.2.0, microsoft/winget-pkgs#469298) is merged, rerun that job in the latest release's run, so winget catches up without waiting for the next release: `gh run rerun <run id> --job <job id>` (the ids are in `gh run view <run id> --json jobs`)
- [ ] The PPA's builds for the new version succeeded on every release and both architectures (https://launchpad.net/~yazeedaloyoun/+archive/ubuntu/proc-cli/+packages)
- [ ] "Update COPR" passed: the build for the new version succeeded on every chroot (https://copr.fedorainfracloud.org/coprs/yazeed/proc-cli/builds/)
Expand Down Expand Up @@ -347,7 +347,7 @@ On tag push, GitHub Actions handles:
6. **Homebrew**: Update yazeed/homebrew-proc tap
7. **Scoop**: Update yazeed/scoop-bucket-proc bucket
8. **Docker**: Push to yazeed/proc-cli on Docker Hub, and the same build to yazeed/proc (the image's original name). A separate workflow (`docker.yml`) with its own tag check: it stops if the tag isn't `v` + Cargo.toml's version
9. **apt repository**: `update-apt` runs `pages.yml`, which deploys proc-cli.com with `/apt` rebuilt from the `.deb` files of the last three releases and signed with `APT_SIGNING_KEY` (`pkg/apt/build-repo.sh`)
9. **apt repository**: `update-apt`, after `commit-package-files`, starts `pages.yml` on main's newest commit and checks that `/apt` lists the release; `pages.yml` deploys proc-cli.com with `/apt` rebuilt from the `.deb` files of the last three releases and signed with `APT_SIGNING_KEY` (`pkg/apt/build-repo.sh`)
10. **winget**: `update-winget` opens the pull request for the new version on microsoft/winget-pkgs from the `yazeed/winget-pkgs` fork, with `WINGET_TOKEN` (winget-releaser; the fork must keep that name). It skips, with a notice, until a first version of `yazeed.proc-cli` is in winget-pkgs
11. **COPR**: `update-copr` sends the version to the project's custom webhook (`COPR_WEBHOOK`). COPR runs the package's build script (`pkg/copr/copr-build.sh`, kept in COPR), which fetches `pkg/copr/sources.sh` and the spec at the tag and makes the source RPM: the spec at that version with a changelog entry, the tag's tarball and every crate `Cargo.lock` names. COPR then builds it for each chroot of `yazeed/proc-cli` (Fedora, EPEL 9 and 10, Amazon Linux 2023); the job follows the build on COPR's API and fails if it fails. Fedora's new releases join the project by themselves ("Follow Fedora branching"). To change the script COPR keeps, edit the file and run `copr-cli edit-package-custom proc-cli --script pkg/copr/copr-build.sh --script-builddeps "curl cargo tar xz"`; `pkg/copr/srpm.sh X.Y.Z` builds the same source RPM locally
12. **PyPI**: `pip install proc-cli` (also `pipx` and `uv tool`). `package-pypi` repacks the five release binaries into five wheels with `pkg/pypi/build-wheels.py` (standard library only; no maturin, no second Rust build): `manylinux_2_17`/`manylinux2014`/`musllinux_1_1` for Linux x86_64 and aarch64 (the static musl binaries), `macosx_10_12_x86_64` and `macosx_11_0_arm64` (each binary's own minimum macOS, read with `vtool -show-build`; check it again when the build target changes) and `win_amd64`, each holding the binary as the `proc` command. It checks the metadata with `twine check` and expects exactly five wheels. `test-pypi` installs the wheel with pip on its own OS (Ubuntu x86_64 and arm64, an Alpine container for musl, macOS arm64 and Intel, Windows) with `pkg/pypi/test-install.sh` and checks `proc --version`. `publish-pypi` runs for a tag, after the GitHub Release and every `test-pypi` job, and uploads the wheels with trusted publishing (environment `pypi`). The wheels are not release files. There is no TestPyPI run: its `proc-cli` belongs to an unrelated project
Expand Down
Loading