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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ but container releases use the upstream-derived format documented in
- Defined the forward-looking first-release roadmap and evidence lifecycle.
- Defined independent versioning for container releases and repository-only
revisions.
- Adopted NGINX-version plus UTC release-date versioning, removed the UBI minor
version from release tags, and prohibited mutable convenience tags for the
first release.
- Added the project overview, intended use cases, security design, rootless
runtime model, and release status.
- Added pinned local pre-commit checks for repository hygiene, shell code,
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,13 +113,14 @@ ghcr.io/datopsis/nginx-ubi9
Container releases will use annotated tags in this form:

```text
v<nginx-version>-ubi<ubi-version>-<packaging-revision>
v<nginx-version>-r<YYYYMMDD>.<daily-sequence>
```

Image releases and repository revisions are deliberately separate. Production
deployments should pin an immutable OCI digest. Repository-only changes are
identified by their full Git commit SHA and do not receive source-only release
tags.
tags. The UBI minor version is recorded in digest-bound release evidence rather
than the tag because it does not uniquely identify the final filesystem.

## Development status

Expand Down
8 changes: 4 additions & 4 deletions docs/PACKAGE-SOURCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,10 @@ license records show that doing so is safe.
## Versioning impact

Changing package suppliers changes image contents and release evidence. Because
no image release exists yet, the first accepted direct-NGINX build can start at
packaging revision `1`. A supplier or channel change after release increments
the packaging revision even when the displayed NGINX and UBI versions remain
the same.
no image release exists yet, the first accepted direct-NGINX build uses the
approved date-based release identifier. A supplier or channel change after
release requires a new immutable release date and daily sequence even when the
displayed NGINX version remains the same.

The package supplier and exact RPM EVR belong in OCI labels, the SBOM,
provenance, and the release evidence. They do not need another field in the
Expand Down
12 changes: 6 additions & 6 deletions docs/ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ are separately approved. They must not delay the core first release.

Work proceeds in this dependency order:

1. Approve the official NGINX stable channel and the first-release versioning
contract before selecting a release tag.
1. Approve the official NGINX stable channel and select the exact NGINX
first-release candidate.
2. Implement architecture-specific artifact locks and source-independent
acquisition driven by protected configuration.
3. Migrate the image to the exact official NGINX RPM and require
Expand Down Expand Up @@ -167,10 +167,10 @@ local evaluation but is not yet a supported release.

## Package 6: signed first release

- [ ] Review and approve the release version contract before selecting or
creating the first release tag. Decide the exact NGINX and named UBI version
fields, packaging revision, mutable convenience-tag policy, support lifetime,
and handling of rebuilds and repository-only changes.
- [ ] Implement and test the approved
`v<nginx-version>-r<YYYYMMDD>.<daily-sequence>` tag contract, UTC date and
sequence validation, immutable release and commit tags, and OCI metadata.
- [ ] Define the first-release support lifetime and superseded-release policy.
- [ ] Freeze the final upstream versions and digests only after image-affecting
work is complete.
- [ ] Review all fixed and unfixed scanner findings against authoritative
Expand Down
88 changes: 67 additions & 21 deletions docs/VERSION.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,40 +10,85 @@ supports.
Annotated release tags use:

```text
v<nginx-version>-ubi<ubi-version>-<packaging-revision>
v<nginx-version>-r<YYYYMMDD>.<daily-sequence>
```

For example, `v1.28.0-ubi9.6-1` would identify:
For example, `v1.30.4-r20260908.1` would identify:

- NGINX `1.28.0`;
- the named UBI `9.6` release; and
- Datopsis packaging revision `1` for that exact NGINX and UBI pair.
- NGINX `1.30.4`;
- a Datopsis container release created on 2026-09-08 UTC; and
- the first container release created on that UTC date.

The example does not select the first release inputs. The actual NGINX and UBI
versions and image digests must be verified and recorded during the upstream
baseline work in `docs/ROADMAP.md`.
The `r` distinguishes this project's container release from an upstream NGINX
source or package version. The eight-digit date is the UTC date on which the
immutable release tag is created. The sequence is a positive integer beginning
at `1` and increments for every additional container release created on the
same UTC date, regardless of NGINX version. Dates must not be backdated.

This upstream-derived format is not Semantic Versioning. The packaging
revision is a positive integer beginning at `1`. It increases monotonically
within one exact NGINX and named UBI pair, even if the project temporarily
releases another pair and later returns to it.
This upstream-derived format is not Semantic Versioning. The downstream
release suffix communicates release chronology; it does not claim
API-compatibility semantics for NGINX configuration.

The tag deliberately omits the UBI minor version. Package updates can make the
runtime filesystem newer than the original base-image snapshot, and a named
minor version does not identify exact bytes. The repository name establishes
the UBI 9 product line. The exact UBI reference and digest remain required in
OCI metadata, the SBOM, provenance, and release evidence.

Release tags are immutable. Never move or reuse a release tag. Production
deployments should pin the OCI digest; a human-readable tag describes a
release, while its digest identifies exact image content.

The release workflow must accept only tags matching:

```regex
^v[0-9]+\.[0-9]+\.[0-9]+-r[0-9]{8}\.[1-9][0-9]*$
```

Pattern matching is only the first check. The workflow must also validate a
real UTC calendar date, the selected NGINX version, the daily sequence against
existing immutable tags, and that the tagged commit is the protected `main`
release commit.

## Artifact identity

The annotated Git tag and immutable GHCR image tag use the complete version,
including the leading `v`. OCI metadata records:

- `org.opencontainers.image.version` as the release identifier without the
leading `v`;
- `org.opencontainers.image.revision` as the full Git commit SHA;
- `org.opencontainers.image.created` as the reproducible UTC creation time;
- the exact UBI base reference and manifest digest;
- the exact NGINX RPM EVR, publisher, and signing identity; and
- the artifact-lock digest used to prepare the build inputs.

The image digest, not any label or tag, is the definitive artifact identity.

## When to change the container version

| Change | Version action |
| --- | --- |
| Change the NGINX version | Use the new NGINX version and revision `1` if that exact NGINX/UBI pair has never been released; otherwise use its next unused revision. |
| Change the named UBI release | Use the new UBI version and revision `1` if the pair is new; otherwise use its next unused revision. |
| Refresh a pinned digest within the same named UBI release | Increment the packaging revision. |
| Change image contents, runtime behavior, default configuration, entrypoint, build inputs, or release metadata | Increment the packaging revision. |
| Change the NGINX version | Use the new NGINX version with the release date and next sequence for that UTC date. |
| Change the UBI reference or digest | Keep the NGINX field and create a release using the current UTC date and next daily sequence. |
| Change an RPM, dependency lock, runtime behavior, default configuration, entrypoint, build input, or release metadata | Create a release using the current UTC date and next daily sequence. |
| Deliberately rebuild otherwise unchanged inputs | Create a release using the current UTC date and next daily sequence. |
| Change only documentation, tests, development tooling, policies, examples not copied into the image, issue templates, or analysis workflows | Do not create or change a container release version unless an image is deliberately republished. |

Every newly published image receives a new release tag, including a deliberate
rebuild whose expected filesystem is unchanged.
Every newly published image receives a new immutable release tag. If more than
one release occurs on a UTC date, inspect existing tags and use the next unused
daily sequence; never fill an older gap or reuse a failed or withdrawn tag.

## Published tags

The first release publishes only:

- the immutable release tag, such as `v1.30.4-r20260908.1`; and
- an immutable `sha-<short-commit>` traceability tag.

Mutable tags such as `latest`, `stable`, `1`, or `1.30` are not published.
They can be considered later only with documented movement, rollback, and
consumer-notification semantics. Controlled deployments use an image digest.

## Repository-only revisions

Expand All @@ -69,7 +114,8 @@ previous release without claiming every entry changed the image filesystem.

Before an annotated release tag is pushed:

1. Verify that the tag's NGINX and UBI versions match the pinned build inputs.
1. Verify that the tag's NGINX version matches the locked RPM and that release
metadata records the exact UBI reference and digest.
2. Convert `Unreleased` changelog entries into a dated section for the tag and
create a new empty `Unreleased` section.
3. Complete the applicable release gates in `docs/ROADMAP.md`.
Expand All @@ -81,5 +127,5 @@ Before an annotated release tag is pushed:
7. Verify the manifest architectures, digest, signature, provenance, SBOM,
labels, scan evidence, and release assets before announcing support.

The release workflow should also publish a `sha-<short-commit>` image tag for
traceability. It supplements but never replaces the release tag and digest.
The `sha-<short-commit>` tag supplements but never replaces the release tag and
digest.
Loading