Release process
On this page
This page describes how coprctl is released. It covers the versioning model,
the two kinds of release (normal and NVR), and the workflow for packaging-only
changes.
The release pipeline is automated with Release Please (GitHub Actions) and
GoReleaser, and Copr builds are triggered from the repository via the SCM
source with auto-rebuild. The full workflow lives in
.github/workflows/release.yml.
Versioning model
There is one source of truth for the version: the Release Please manifest
(.release-please-manifest.json), which drives a semantic version
(0.1.0, 0.2.0, ...). Release Please owns:
- the semantic version and the
v<semver>git tag, - the
CHANGELOG.mdand the GitHub release, - and, via the
extra-filesconfiguration, theVersion:line incoprctl.spec, so the RPM version always matches the semantic version.
The tag is a bare v<semver> (for example v0.4.0) so GoReleaser can parse it
as a semantic version. Copr's tag-triggered rebuild matches the package via a
package-scoped webhook URL (which names the package), so the tag does not need
to encode the package name.
The RPM Release field is separate and independent. It is how Copr distinguishes multiple builds of the same version. This gives two release paths, described below.
Release Please conventions
Because Release Please derives the next version from conventional commits, the repo follows these rules:
- Pull request only. All changes land on
mainthrough a pull request, never by pushing directly tomain. - Squash merge. Merge with a squash merge so each merged PR contributes exactly one commit with a conventional-commit message. This is what Release Please parses to compute the next version and build the changelog.
- Conventional commits. The merged commit message determines the bump:
fix:bumps the patch,feat:bumps the minor, and a breaking change (a!orBREAKING CHANGE:body) bumps the major. Changelog sections are grouped from these prefixes.
Release Please opens a release pull request (titled
chore: release <branch>) that bumps the version, updates coprctl.spec
Version:, and rewrites CHANGELOG.md. Merging that PR publishes the
v<semver> tag and the GitHub release, which triggers the GoReleaser build.
Normal releases
A normal release publishes a new semantic version:
- Merge feature and fix pull requests to
mainwith squash merges and conventional-commit messages. - Release Please opens a release PR that bumps the version and the spec
Version:field. - Review and squash-merge the release PR.
- The
v<semver>tag is created and the GitHub release is published. - GoReleaser builds and uploads artifacts (tarballs and checksums).
- Copr rebuilds
coprctlfrommain(auto-rebuild on the SCM source), sodnf copr enable abn/coprctl && dnf install coprctlinstalls the new version.
The RPM version equals the semantic version: coprctl-<version>-1.fcNN.
NVR releases
An NVR (name-version-release) release republishes the same version with a
different release number, without a new semantic version. Use this to fix a
packaging problem (a spec bug, a missing BuildRequires, a wrong build flag)
without bumping the application version.
The RPM Release field starts at 1 and is bumped manually:
- Edit
coprctl.specand incrementRelease:(for example1%{?dist}to2%{?dist}). - Commit and open a pull request. Use a conventional-commit message such as
fix(packaging): ...so it is captured correctly. - Squash-merge the PR.
- Push a tag in
N-V-Rform:coprctl-<version>-<release>(for examplecoprctl-0.4.7-2). The webhook is tag-only, so a plain branch push does not rebuild; the tag is the trigger.
The tag fires the same package-scoped webhook as a release tag and Copr
rebuilds the package, producing coprctl-<version>-2.fcNN. The semantic
version and the v<semver> tag are unchanged. NVR releases are common and
inexpensive; there is no need to bump the version for a packaging fix.
Why the tag: Copr matches a tag to a package either through the package-scoped
webhook URL (which names the package) or through the N-V/N-V-R shape of
the tag itself. A bare v<semver> tag cannot be reused for an NVR release, so
the N-V-R form carries both the version and the release that the webhook
should build.
Packaging-only changes
A change that touches only the packaging (the spec, the manifest, the GoReleaser or release config) still goes through the same PR-only, squash-merge flow. Decide which release path applies:
- If the change only affects how the package is built (a build flag, a
dependency, a
Source0change), it is an NVR release: bumpRelease:, merge, and push theN-V-Rtag so Copr rebuilds. - If the change is a user-facing feature or fix (new command, changed behavior),
it is a normal release: merge with
feat:/fix:and let Release Please open the version-bumping release PR.
There is no separate branch or process for packaging-only work; it reuses the same pull request and squash-merge convention.
Working with Release Please
- Do not edit
CHANGELOG.mdor the version by hand. Release Please owns both. Edit only through its release PR. - Keep
coprctl.spec'sVersion:in sync. TheVersion:tag sits inside a release-please version block (x-release-please-start-version...endcomment lines). The markers are plain spec comments so rpmbuild parses the tag cleanly; do not move them back onto theVersion:line as a trailing comment, which rpmbuild rejects with "Tag takes single token only". - Respect the manifest.
.release-please-manifest.jsonrecords the last released version. Do not edit it by hand except during bootstrap. - Preview the next release. Run
release-please release-prlocally (or in CI) to see the proposed bump before merging.
Related
- Contribution guide for the contribution workflow.
- Maintainer guide for the review gate.
- The release workflow:
.github/workflows/release.yml.