uttrflow / uttrflow/uttrflow-swift
Nothing checks the release-notes step before a tag: its shell and the changelog section it reads only ever run on the tag push
- Dominant language
- Swift
- Stars
- 4
- Forks
- 17
- Avg merge
- 3h 32m
- Merged PRs (30d)
- 277
Description
## What happens
The `notes` job in `.github/workflows/release.yml:118-137` builds the release body with `./Scripts/changelog.py "$VERSION"` and two `printf` lines, then calls `gh release create`. That block runs only on `push: tags: ["v*"]`. Nothing on a pull request or in `make verify` executes it or checks that `CHANGELOG.md` has a section for the version in `Resources/Uttrflow-Info.plist`.
That is how #472 happened: `printf '- Every build: ...'` made bash read `- ` as an option, the job exited 2 on the `v2026.9.14` tag, and no release was created on this repository until it was made by hand. The mistake was only discoverable by tagging.
`actionlint` in `quality.yml` runs shellcheck over the block, but shellcheck does not flag a `printf` format string that starts with `-`.
## Why it matters
A release is the one step that cannot be retried quietly: the tag is public the moment it is pushed. A check that costs seconds on a Linux runner turns a failure on release day into a red pull request.
## Acceptance criteria
- The notes block moves into a script (for example `Scripts/release_notes.sh VERSION`) that `release.yml` calls, so the workflow and the check run the same lines.
- A job in `.github/workflows/quality.yml` (Linux, no secrets) runs that script for the version read from `Resources/Uttrflow-Info.plist` and fails if it exits non-zero or prints nothing. If the plist's version has no section yet, it runs it for the newest section in `CHANGELOG.md` instead, so an ordinary pull request does not fail between releases.
- Reintroducing `printf '- x'` into the script makes that job fail (say in the pull request that you tried it).
- `make verify` and `actionlint` still pass.
## Where to start
- `.github/workflows/release.yml` lines 104-137, `Scripts/changelog.py` (`--check` already exists), `.github/workflows/quality.yml`.
- `RELEASING.md` "Cutting a release" step two describes the changelog step the check protects.
- Read [CONTRIBUTING.md](https://github.com/uttrflow/uttrflow-swift/blob/main/CONTRIBUTING.md) first, and say on this issue that you are taking it.
- Before pushing, run `make verify` (with `DEVELOPER_DIR` pointing at Xcode 26.6 or later). It is the same command CI runs.
**Size:** S, about 2 hours.
Contributor guide
Research direction
Read CONTRIBUTING.md first, then inspect the notes block in .github/workflows/release.yml:104-137, Scripts/changelog.py, and .github/workflows/quality.yml. Extract the release-notes entry point into Scripts/release_notes.sh VERSION and make the Linux quality job exercise it, including the plist/changelog fallback. Run make verify and actionlint; done means the check rejects the bad printf case and release.yml still uses the script.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- github-actions, python, shell, swift
- Domain
- build-system, ci-cd, release
- Issue type
- Refactor
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 70/100