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: 1 addition & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,11 @@ jobs:
flavor: |
latest=${{ (inputs.tag != '' && 'true') || 'auto' }}
tags: |
type=semver,pattern={{version}},suffix=${{ inputs.build-os != '' && format('-{0}', inputs.build-os) || '' }}
type=semver,pattern={{version}},value=${{ inputs.tag }},enable=${{ inputs.tag != '' }},suffix=${{ inputs.build-os != '' && format('-{0}', inputs.build-os) || '' }}
type=edge,suffix=${{ inputs.build-os != '' && format('-{0}', inputs.build-os) || '' }}
type=schedule,suffix=${{ inputs.build-os != '' && format('-{0}', inputs.build-os) || '' }}
type=ref,event=pr,suffix=${{ inputs.build-os != '' && format('-{0}', inputs.build-os) || '' }}
type=ref,event=branch,suffix=-rc${{ inputs.build-os != '' && format('-{0}', inputs.build-os) || '' }},enable=${{ startsWith(github.ref, 'refs/heads/release') && inputs.tag == '' }}
type=raw,value=${{ inputs.tag }},enable=${{ inputs.tag != '' }},suffix=${{ inputs.build-os != '' && format('-{0}', inputs.build-os) || '' }}
labels: |
org.opencontainers.image.documentation=https://docs.nginx.com/nginx-gateway-fabric
org.opencontainers.image.vendor=NGINX Inc <[email protected]>
Expand Down
67 changes: 64 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,25 @@ on:
- "**"
schedule:
- cron: "0 3 * * *" # run every day at 3am UTC (nightly builds)
workflow_call:
workflow_dispatch:
inputs:
is_production_release:
description: 'Is this a production release?'
required: false
type: boolean
default: false
release_version:
description: 'Release version (e.g., v2.0.3)'
required: false
type: string
default: ''
operator_version:
description: 'Operator release version (e.g., v1.0.0). Optional'
required: false
type: string
default: ''
dry_run:
description: 'If true, does a dry run of the production workflow'
required: false
type: boolean
default: false
Expand All @@ -34,13 +38,70 @@ defaults:
shell: bash

concurrency:
group: ${{ github.ref_name }}-ci
cancel-in-progress: true
group: ${{ inputs.is_production_release && format('prod-{0}', inputs.release_version) || format('{0}-ci', github.ref_name) }}
cancel-in-progress: ${{ !inputs.is_production_release }}

permissions:
contents: read

jobs:
create-tag-and-release:
runs-on: ubuntu-24.04
if: github.event_name == 'workflow_dispatch' && inputs.release_version != '' && startsWith(github.ref, 'refs/heads/release-')
permissions:
contents: write
steps:
- name: Validate Release Branch and Version
run: |
echo "Validating release from: ${GITHUB_REF}"

INPUT_VERSION="${{ inputs.release_version }}"
INPUT_OPERATOR_VERSION="${{ inputs.operator_version }}"

# Validate version format
if [[ ! "${INPUT_VERSION}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "❌ Invalid version format: ${INPUT_VERSION}"
echo "Expected format: v1.2.3"
exit 1
fi

# Validate version format if operator version is provided
if [[ -n "${INPUT_OPERATOR_VERSION}" && ! "${INPUT_OPERATOR_VERSION}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "❌ Invalid operator version format: ${INPUT_OPERATOR_VERSION}"
echo "Expected format: v1.2.3"
exit 1
fi

echo "✅ Valid release branch: ${GITHUB_REF}"
echo "✅ Valid version format: ${INPUT_VERSION}"
[[ -n "${INPUT_OPERATOR_VERSION}" ]] && echo "✅ Valid operator version format: ${INPUT_OPERATOR_VERSION}"

- name: Checkout Repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
fetch-depth: 0

- name: Create Release Tag
run: |
VERSION="${{ inputs.release_version }}"
git config user.name "NGF Release Bot"
git config user.email "[email protected]"

if git rev-parse --verify "refs/tags/${VERSION}" >/dev/null 2>&1; then
echo "Tag ${VERSION} already exists - skipping tag creation"
else
echo "Creating annotated tag ${VERSION}"
git tag -a "${VERSION}" -m "Release ${VERSION}"

if [[ "${{ inputs.dry_run }}" == "true" ]]; then
echo "DRY RUN: Would push tag ${VERSION} and operator tag ${{ inputs.operator_version || '' }}"
git push --dry-run origin "${VERSION}"
else
git push origin "${VERSION}"
echo "Created and pushed tag: ${VERSION}"
fi
fi

vars:
name: Checks and variables
runs-on: ubuntu-24.04
Expand Down
6 changes: 2 additions & 4 deletions .github/workflows/helm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,11 @@ jobs:
images: |
name=ghcr.io/nginx/nginx-gateway-fabric
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{version}},value=${{ inputs.tag }},enable=${{ inputs.tag != '' }}
type=edge
type=schedule
type=ref,event=pr
type=ref,event=branch,suffix=-rc,enable=${{ startsWith(github.ref, 'refs/heads/release') && inputs.tag == '' }}
type=raw,value=${{ inputs.tag }},enable=${{ inputs.tag != '' }}

- name: NGINX Docker meta
id: nginx-meta
Expand All @@ -58,12 +57,11 @@ jobs:
images: |
name=ghcr.io/nginx/nginx-gateway-fabric/${{ inputs.image == 'plus' && 'nginx-plus' || inputs.image }}
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{version}},value=${{ inputs.tag }},enable=${{ inputs.tag != '' }}
type=edge
type=schedule
type=ref,event=pr
type=ref,event=branch,suffix=-rc,enable=${{ startsWith(github.ref, 'refs/heads/release') && inputs.tag == '' }}
type=raw,value=${{ inputs.tag }},enable=${{ inputs.tag != '' }}

- name: Build NGF Docker Image
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
Expand Down
102 changes: 0 additions & 102 deletions .github/workflows/production-release.yml

This file was deleted.

9 changes: 7 additions & 2 deletions docs/developer/release-process.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,13 @@ To create a new release, follow these steps:
created. If included, use the Release Notes specified in a PR.
- If the supported Gateway API minor version has changed since the last release, add a note to the release notes explaining if the previous version is no longer supported.
- Merge the release PR once it has received all necessary approvals.
6. Once you are ready to release, run the [Production Release](https://github.com/nginx/nginx-gateway-fabric/actions/workflows/production-release.yml) workflow with the correct tag e.g. `v2.1.0`. (Note: It is also possible to do a dry run of the production release workflow for verification if required. This will not push the tag, images, and chart, and won't publish the release)
If this release includes an updated release of our [Operator](https://github.com/nginx/nginx-gateway-fabric/tree/main/operators), include the new version as well e.g. `v1.0.1`
6. Once you are ready to release, trigger a production release by running the [CI workflow](https://github.com/nginx/nginx-gateway-fabric/actions/workflows/ci.yml) with the following inputs:
- Select the release branch (e.g., `release-2.2`)
- Set `is_production_release` to `true` (checked)
- Set `release_version` to the release tag (e.g., `v2.2.0`)
- If this release includes an updated release of our [Operator](https://github.com/nginx/nginx-gateway-fabric/tree/main/operators), set `operator_version` to the new version (e.g., `v1.0.1`)
- Set `dry_run` to `false` (unchecked) for a real release, or `true` for a dry run (Note: A dry run will not push the tag, images, and chart, and won't publish the release)

As a result, the CI/CD pipeline will:
- Create and push the tag
- Build NGF, NGINX and NGINX Plus container images with the release tag `X.Y.Z` and push them to the registries.
Expand Down
Loading