Releases and security¶
How a change becomes a signed release, and the security checks of every repository.
Releases¶
A pull request with the next version, decided from the titles of the merged pull requests (fix a patch, feat a minor, ! a major version, or a minor one while the version is below 1.0.0), and the text of the fragments in changelog.d/ and of Unreleased in the changelog as its notes; merging it publishes the release with its package, SBOM and the signed provenance of an isolated build (SLSA Build Level 3), delivers it, and then verifies it as its users can, also every week; where the repository variable BETA_CHANNEL is true, every change for users also becomes a beta of the next release, a prerelease for testers.
How: Release-please, the release app, immutable releases, verify-release.yml.
From a change to a release¶
The title of a pull request decides the next version, and merging the release pull request does the rest:
A pull request describes what it changes for users in a file of its own, a fragment in changelog.d/, such as changelog.d/dark-mode.md, below the heading of its kind of change, such as ### Features. A new file conflicts with nothing, so pull requests that run at the same time merge one after another, without a person who merges main into each of them, and a release no longer conflicts with the pull requests that wait. The check of the title, conventional title, checks each fragment of a pull request as the release takes it in and counts only a new one as its entry, scripts/check.sh checks every fragment that waits on main as well, and the release bot moves every fragment into the section of the release and deletes it in the same commit. A heading that surely means a kind of change, such as ### Fixes for ### Fixed or ## Features for ### Features, the fix bot renames on the branch of the pull request and suggests on one from a fork; one as close to one kind as to another, such as ### Change, stays for its author. Until the release, a page of the website that includes CHANGELOG.md, such as the changelog of this one, shows the entries of the fragments under Unreleased, grouped as the release groups them. A line under ## Unreleased in CHANGELOG.md still works.
release-please reads the title of each merged pull request, not its whole description. The squash commit carries the description, and a line of it that the strict parser of release-please takes for a footer, such as **[(Full of the release notes that Renovate quotes, made it skip the commit in a run that passed, so that a fix waited for another release, which didn't list it. So before release-please runs, the release bot writes the title and the lines Release-As: and BREAKING CHANGE: of each pull request since the last release that can change it into the end of its description, as an override in an HTML comment that the page doesn't show; an edit that GitHub refuses is a warning, and release-please runs anyway. The release pull request changes only when its notes change; release-please rebuilt it in every run before, and every check of it started again (decision 0060 of the decisions).
Each release describes what it ships in its SBOMs, as SPDX and as CycloneDX: the package that its users install, or the files of its tag without those that only check, test and document it, under the name of the repository and the version of the release. A scanner of a user reports only the advisories of what the release ships, and applies its OpenVEX document to them (decision 0034 of the decisions):
A release of paperless-sync, as GitHub shows its assets: the signed app, its signature, its SBOMs as CycloneDX and SPDX, the provenance of its build with its Sigstore bundle, the notices of its dependencies, and the attestation of the release:
Security¶
CodeQL, and for the PHP of a Nextcloud app the taint analysis of Psalm, which knows the controllers, files and HTTP client of Nextcloud and proves with a canary in every run that it still sees, OpenSSF Scorecard, dependency review, secret scan, SBOMs of what a release ships as SPDX and CycloneDX, by its name and version, OpenVEX, release tags signed without a key (gitsign) and checked before every build, findings watcher, the security audit of the workflows (zizmor), every lock file against the OSV database (OSV-Scanner), the network traffic of every job (Harden-Runner), blocked in each job that holds a secret or may write but for the hosts it needs, the answers of OpenSSF Best Practices and of the OSPS Baseline that the blueprint guarantees (.bestpractices.json).
How: Every action pinned to a commit hash.
App Store¶
For a Nextcloud app: the registration of its id with its certificate, once, by hand.
How: register-app.yml.

