feat: enable forks to release and publish to custom quay registries (#25365)

Signed-off-by: reggie-k <regina.voloshin@codefresh.io>
Signed-off-by: Regina Voloshin <regina.voloshin@codefresh.io>
This commit is contained in:
Regina Voloshin
2025-12-09 17:38:01 +02:00
committed by GitHub
parent fa609efbc1
commit 4ea93dbdc0
12 changed files with 244 additions and 48 deletions

View File

@@ -194,7 +194,7 @@ jobs:
- name: Checkout code
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Create symlink in GOPATH
run: ln -s $(pwd) ~/go/src/github.com/argoproj/argo-cd
run: ln -s $(pwd) ~/go/src/github.com/argoproj/argo-cd
- name: Setup Golang
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
with:
@@ -256,9 +256,10 @@ jobs:
with:
go-version: ${{ env.GOLANG_VERSION }}
- name: Create symlink in GOPATH
# generalizing repo name for forks: ${{ github.event.repository.name }}
run: |
mkdir -p ~/go/src/github.com/argoproj
cp -a ../argo-cd ~/go/src/github.com/argoproj
cp -a ../${{ github.event.repository.name }} ~/go/src/github.com/argoproj
- name: Add ~/go/bin to PATH
run: |
echo "/home/runner/go/bin" >> $GITHUB_PATH
@@ -270,12 +271,14 @@ jobs:
# We need to vendor go modules for codegen yet
go mod download
go mod vendor -v
working-directory: /home/runner/go/src/github.com/argoproj/argo-cd
# generalizing repo name for forks: ${{ github.event.repository.name }}
working-directory: /home/runner/go/src/github.com/argoproj/${{ github.event.repository.name }}
- name: Install toolchain for codegen
run: |
make install-codegen-tools-local
make install-go-tools-local
working-directory: /home/runner/go/src/github.com/argoproj/argo-cd
# generalizing repo name for forks: ${{ github.event.repository.name }}
working-directory: /home/runner/go/src/github.com/argoproj/${{ github.event.repository.name }}
# We install kustomize in the dist directory
- name: Add dist to PATH
run: |
@@ -286,12 +289,14 @@ jobs:
export GOPATH=$(go env GOPATH)
git checkout -- go.mod go.sum
make codegen-local
working-directory: /home/runner/go/src/github.com/argoproj/argo-cd
# generalizing repo name for forks: ${{ github.event.repository.name }}
working-directory: /home/runner/go/src/github.com/argoproj/${{ github.event.repository.name }}
- name: Check nothing has changed
run: |
set -xo pipefail
git diff --exit-code -- . ':!go.sum' ':!go.mod' ':!assets/swagger.json' | tee codegen.patch
working-directory: /home/runner/go/src/github.com/argoproj/argo-cd
# generalizing repo name for forks: ${{ github.event.repository.name }}
working-directory: /home/runner/go/src/github.com/argoproj/${{ github.event.repository.name }}
build-ui:
name: Build, test & lint UI code
@@ -406,7 +411,7 @@ jobs:
test-e2e:
name: Run end-to-end tests
if: ${{ needs.changes.outputs.backend == 'true' }}
runs-on: oracle-vm-16cpu-64gb-x86-64
runs-on: ${{ github.repository == 'argoproj/argo-cd' && 'oracle-vm-16cpu-64gb-x86-64' || 'ubuntu-22.04' }}
strategy:
fail-fast: false
matrix:
@@ -425,7 +430,6 @@ jobs:
- build-go
- changes
env:
GOPATH: /home/ubuntu/go
ARGOCD_FAKE_IN_CLUSTER: 'true'
ARGOCD_SSH_DATA_PATH: '/tmp/argo-e2e/app/config/ssh'
ARGOCD_TLS_DATA_PATH: '/tmp/argo-e2e/app/config/tls'
@@ -451,6 +455,9 @@ jobs:
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
with:
go-version: ${{ env.GOLANG_VERSION }}
- name: Set GOPATH
run: |
echo "GOPATH=$HOME/go" >> $GITHUB_ENV
- name: GH actions workaround - Kill XSP4 process
run: |
sudo pkill mono || true
@@ -461,9 +468,9 @@ jobs:
set -x
curl -sfL https://get.k3s.io | sh -
sudo chmod -R a+rw /etc/rancher/k3s
sudo mkdir -p $HOME/.kube && sudo chown -R ubuntu $HOME/.kube
sudo mkdir -p $HOME/.kube && sudo chown -R $(whoami) $HOME/.kube
sudo k3s kubectl config view --raw > $HOME/.kube/config
sudo chown ubuntu $HOME/.kube/config
sudo chown $(whoami) $HOME/.kube/config
sudo chmod go-r $HOME/.kube/config
kubectl version
- name: Restore go build cache
@@ -473,7 +480,7 @@ jobs:
key: ${{ runner.os }}-go-build-v1-${{ github.run_id }}
- name: Add ~/go/bin to PATH
run: |
echo "/home/ubuntu/go/bin" >> $GITHUB_PATH
echo "$HOME/go/bin" >> $GITHUB_PATH
- name: Add /usr/local/bin to PATH
run: |
echo "/usr/local/bin" >> $GITHUB_PATH
@@ -499,7 +506,7 @@ jobs:
- name: Create target directory for binaries in the build-process
run: |
mkdir -p dist
chown ubuntu dist
chown $(whoami) dist
- name: Run E2E server and wait for it being available
timeout-minutes: 30
run: |

View File

@@ -19,16 +19,49 @@ jobs:
set-vars:
permissions:
contents: read
if: github.repository == 'argoproj/argo-cd'
# Always run to calculate variables - other jobs check outputs
runs-on: ubuntu-22.04
outputs:
image-tag: ${{ steps.image.outputs.tag}}
platforms: ${{ steps.platforms.outputs.platforms }}
image_namespace: ${{ steps.image.outputs.image_namespace }}
image_repository: ${{ steps.image.outputs.image_repository }}
quay_image_name: ${{ steps.image.outputs.quay_image_name }}
ghcr_image_name: ${{ steps.image.outputs.ghcr_image_name }}
ghcr_provenance_image: ${{ steps.image.outputs.ghcr_provenance_image }}
allow_ghcr_publish: ${{ steps.image.outputs.allow_ghcr_publish }}
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Set image tag for ghcr
run: echo "tag=$(cat ./VERSION)-${GITHUB_SHA::8}" >> $GITHUB_OUTPUT
- name: Set image tag and names
run: |
# Calculate image tag
TAG="$(cat ./VERSION)-${GITHUB_SHA::8}"
echo "tag=$TAG" >> $GITHUB_OUTPUT
# Calculate image names with defaults
IMAGE_NAMESPACE="${{ vars.IMAGE_NAMESPACE || 'argoproj' }}"
IMAGE_REPOSITORY="${{ vars.IMAGE_REPOSITORY || 'argocd' }}"
GHCR_NAMESPACE="${{ vars.GHCR_NAMESPACE || github.repository }}"
GHCR_REPOSITORY="${{ vars.GHCR_REPOSITORY || 'argocd' }}"
echo "image_namespace=$IMAGE_NAMESPACE" >> $GITHUB_OUTPUT
echo "image_repository=$IMAGE_REPOSITORY" >> $GITHUB_OUTPUT
# Construct image name
echo "quay_image_name=quay.io/$IMAGE_NAMESPACE/$IMAGE_REPOSITORY:latest" >> $GITHUB_OUTPUT
ALLOW_GHCR_PUBLISH=false
if [[ "${{ github.repository }}" == "argoproj/argo-cd" || "$GHCR_NAMESPACE" != argoproj/* ]]; then
ALLOW_GHCR_PUBLISH=true
echo "ghcr_image_name=ghcr.io/$GHCR_NAMESPACE/$GHCR_REPOSITORY:$TAG" >> $GITHUB_OUTPUT
echo "ghcr_provenance_image=ghcr.io/$GHCR_NAMESPACE/$GHCR_REPOSITORY" >> $GITHUB_OUTPUT
else
echo "GhCR publish skipped: refusing to push to namespace '$GHCR_NAMESPACE'. Please override GHCR_* for forks." >&2
echo "ghcr_image_name=" >> $GITHUB_OUTPUT
echo "ghcr_provenance_image=" >> $GITHUB_OUTPUT
fi
echo "allow_ghcr_publish=$ALLOW_GHCR_PUBLISH" >> $GITHUB_OUTPUT
id: image
- name: Determine image platforms to use
@@ -48,7 +81,7 @@ jobs:
contents: read
packages: write # for pushing packages to GHCR, which is used by cd.apps.argoproj.io to avoid polluting Quay with tags
id-token: write # for creating OIDC tokens for signing.
if: ${{ github.repository == 'argoproj/argo-cd' && github.event_name != 'push' }}
if: ${{ (github.repository == 'argoproj/argo-cd' || needs.set-vars.outputs.image_namespace != 'argoproj') && github.event_name != 'push' }}
uses: ./.github/workflows/image-reuse.yaml
with:
# Note: cannot use env variables to set go-version (https://docs.github.com/en/actions/using-workflows/reusing-workflows#limitations)
@@ -63,11 +96,11 @@ jobs:
contents: read
packages: write # for pushing packages to GHCR, which is used by cd.apps.argoproj.io to avoid polluting Quay with tags
id-token: write # for creating OIDC tokens for signing.
if: ${{ github.repository == 'argoproj/argo-cd' && github.event_name == 'push' }}
if: ${{ (github.repository == 'argoproj/argo-cd' || needs.set-vars.outputs.image_namespace != 'argoproj') && github.event_name == 'push' }}
uses: ./.github/workflows/image-reuse.yaml
with:
quay_image_name: quay.io/argoproj/argocd:latest
ghcr_image_name: ghcr.io/argoproj/argo-cd/argocd:${{ needs.set-vars.outputs.image-tag }}
quay_image_name: ${{ needs.set-vars.outputs.quay_image_name }}
ghcr_image_name: ${{ needs.set-vars.outputs.ghcr_image_name }}
# Note: cannot use env variables to set go-version (https://docs.github.com/en/actions/using-workflows/reusing-workflows#limitations)
# renovate: datasource=golang-version packageName=golang
go-version: 1.25.3
@@ -81,16 +114,17 @@ jobs:
build-and-publish-provenance: # Push attestations to GHCR, latest image is polluting quay.io
needs:
- set-vars
- build-and-publish
permissions:
actions: read # for detecting the Github Actions environment.
id-token: write # for creating OIDC tokens for signing.
packages: write # for uploading attestations. (https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/container/README.md#known-issues)
if: ${{ github.repository == 'argoproj/argo-cd' && github.event_name == 'push' }}
if: ${{ (github.repository == 'argoproj/argo-cd' || needs.set-vars.outputs.image_namespace != 'argoproj') && github.event_name == 'push' && needs.set-vars.outputs.allow_ghcr_publish == 'true'}}
# Must be refernced by a tag. https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/container/README.md#referencing-the-slsa-generator
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.1.0
with:
image: ghcr.io/argoproj/argo-cd/argocd
image: ${{ needs.set-vars.outputs.ghcr_provenance_image }}
digest: ${{ needs.build-and-publish.outputs.image-digest }}
registry-username: ${{ github.actor }}
secrets:

View File

@@ -21,6 +21,12 @@ jobs:
pull-requests: write # for peter-evans/create-pull-request to create a PR
name: Automatically generate version and manifests on ${{ inputs.TARGET_BRANCH }}
runs-on: ubuntu-22.04
env:
# Calculate image names with defaults, this will be used in the make manifests-local command
# to generate the correct image name in the manifests
IMAGE_REGISTRY: ${{ vars.IMAGE_REGISTRY || 'quay.io' }}
IMAGE_NAMESPACE: ${{ vars.IMAGE_NAMESPACE || 'argoproj' }}
IMAGE_REPOSITORY: ${{ vars.IMAGE_REPOSITORY || 'argocd' }}
steps:
- name: Checkout code
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1

View File

@@ -15,14 +15,15 @@ env:
jobs:
argocd-image:
needs: [setup-variables]
permissions:
contents: read
id-token: write # for creating OIDC tokens for signing.
packages: write # used to push images to `ghcr.io` if used.
if: github.repository == 'argoproj/argo-cd'
if: github.repository == 'argoproj/argo-cd' || needs.setup-variables.outputs.allow_fork_release == 'true'
uses: ./.github/workflows/image-reuse.yaml
with:
quay_image_name: quay.io/argoproj/argocd:${{ github.ref_name }}
quay_image_name: ${{ needs.setup-variables.outputs.quay_image_name }}
# Note: cannot use env variables to set go-version (https://docs.github.com/en/actions/using-workflows/reusing-workflows#limitations)
# renovate: datasource=golang-version packageName=golang
go-version: 1.25.3
@@ -34,11 +35,17 @@ jobs:
setup-variables:
name: Setup Release Variables
if: github.repository == 'argoproj/argo-cd'
if: github.repository == 'argoproj/argo-cd' || (github.repository_owner != 'argoproj' && vars.ENABLE_FORK_RELEASES == 'true' && vars.IMAGE_NAMESPACE && vars.IMAGE_NAMESPACE != 'argoproj')
runs-on: ubuntu-22.04
outputs:
is_pre_release: ${{ steps.var.outputs.is_pre_release }}
is_latest_release: ${{ steps.var.outputs.is_latest_release }}
enable_fork_releases: ${{ steps.var.outputs.enable_fork_releases }}
image_namespace: ${{ steps.var.outputs.image_namespace }}
image_repository: ${{ steps.var.outputs.image_repository }}
quay_image_name: ${{ steps.var.outputs.quay_image_name }}
provenance_image: ${{ steps.var.outputs.provenance_image }}
allow_fork_release: ${{ steps.var.outputs.allow_fork_release }}
steps:
- name: Checkout code
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
@@ -67,18 +74,36 @@ jobs:
fi
echo "is_pre_release=$PRE_RELEASE" >> $GITHUB_OUTPUT
echo "is_latest_release=$IS_LATEST" >> $GITHUB_OUTPUT
# Calculate configuration with defaults
ENABLE_FORK_RELEASES="${{ vars.ENABLE_FORK_RELEASES || 'false' }}"
IMAGE_NAMESPACE="${{ vars.IMAGE_NAMESPACE || 'argoproj' }}"
IMAGE_REPOSITORY="${{ vars.IMAGE_REPOSITORY || 'argocd' }}"
echo "enable_fork_releases=$ENABLE_FORK_RELEASES" >> $GITHUB_OUTPUT
echo "image_namespace=$IMAGE_NAMESPACE" >> $GITHUB_OUTPUT
echo "image_repository=$IMAGE_REPOSITORY" >> $GITHUB_OUTPUT
echo "quay_image_name=quay.io/$IMAGE_NAMESPACE/$IMAGE_REPOSITORY:${{ github.ref_name }}" >> $GITHUB_OUTPUT
echo "provenance_image=quay.io/$IMAGE_NAMESPACE/$IMAGE_REPOSITORY" >> $GITHUB_OUTPUT
ALLOW_FORK_RELEASE=false
if [[ "${{ github.repository_owner }}" != "argoproj" && "$ENABLE_FORK_RELEASES" == "true" && "$IMAGE_NAMESPACE" != "argoproj" && "${{ github.ref }}" == refs/tags/* ]]; then
ALLOW_FORK_RELEASE=true
fi
echo "allow_fork_release=$ALLOW_FORK_RELEASE" >> $GITHUB_OUTPUT
argocd-image-provenance:
needs: [argocd-image]
needs: [setup-variables, argocd-image]
permissions:
actions: read # for detecting the Github Actions environment.
id-token: write # for creating OIDC tokens for signing.
packages: write # for uploading attestations. (https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/container/README.md#known-issues)
# Must be refernced by a tag. https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/container/README.md#referencing-the-slsa-generator
if: github.repository == 'argoproj/argo-cd'
if: github.repository == 'argoproj/argo-cd' || needs.setup-variables.outputs.allow_fork_release == 'true'
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.1.0
with:
image: quay.io/argoproj/argocd
image: ${{ needs.setup-variables.outputs.provenance_image }}
digest: ${{ needs.argocd-image.outputs.image-digest }}
secrets:
registry-username: ${{ secrets.RELEASE_QUAY_USERNAME }}
@@ -91,7 +116,7 @@ jobs:
- argocd-image-provenance
permissions:
contents: write # used for uploading assets
if: github.repository == 'argoproj/argo-cd'
if: github.repository == 'argoproj/argo-cd' || needs.setup-variables.outputs.allow_fork_release == 'true'
runs-on: ubuntu-22.04
env:
GORELEASER_MAKE_LATEST: ${{ needs.setup-variables.outputs.is_latest_release }}
@@ -143,6 +168,8 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
KUBECTL_VERSION: ${{ env.KUBECTL_VERSION }}
GIT_TREE_STATE: ${{ env.GIT_TREE_STATE }}
# Used to determine the current repository in the goreleaser config to display correct manifest links
GORELEASER_CURRENT_REPOSITORY: ${{ github.repository }}
- name: Generate subject for provenance
id: hash
@@ -159,12 +186,12 @@ jobs:
echo "hashes=$hashes" >> $GITHUB_OUTPUT
goreleaser-provenance:
needs: [goreleaser]
needs: [goreleaser, setup-variables]
permissions:
actions: read # for detecting the Github Actions environment
id-token: write # Needed for provenance signing and ID
contents: write # Needed for release uploads
if: github.repository == 'argoproj/argo-cd'
if: github.repository == 'argoproj/argo-cd' || needs.setup-variables.outputs.allow_fork_release == 'true'
# Must be refernced by a tag. https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/container/README.md#referencing-the-slsa-generator
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0
with:
@@ -177,11 +204,12 @@ jobs:
needs:
- argocd-image
- goreleaser
- setup-variables
permissions:
contents: write # Needed for release uploads
outputs:
hashes: ${{ steps.sbom-hash.outputs.hashes }}
if: github.repository == 'argoproj/argo-cd'
if: github.repository == 'argoproj/argo-cd' || needs.setup-variables.outputs.allow_fork_release == 'true'
runs-on: ubuntu-22.04
steps:
- name: Checkout code
@@ -207,7 +235,7 @@ jobs:
# managers (gomod, yarn, npm).
PROJECT_FOLDERS: '.,./ui'
# full qualified name of the docker image to be inspected
DOCKER_IMAGE: quay.io/argoproj/argocd:${{ github.ref_name }}
DOCKER_IMAGE: ${{ needs.setup-variables.outputs.quay_image_name }}
run: |
yarn install --cwd ./ui
go install github.com/spdx/spdx-sbom-generator/cmd/generator@$SPDX_GEN_VERSION
@@ -244,12 +272,12 @@ jobs:
/tmp/sbom.tar.gz
sbom-provenance:
needs: [generate-sbom]
needs: [generate-sbom, setup-variables]
permissions:
actions: read # for detecting the Github Actions environment
id-token: write # Needed for provenance signing and ID
contents: write # Needed for release uploads
if: github.repository == 'argoproj/argo-cd'
if: github.repository == 'argoproj/argo-cd' || needs.setup-variables.outputs.allow_fork_release == 'true'
# Must be referenced by a tag. https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/container/README.md#referencing-the-slsa-generator
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0
with:
@@ -266,7 +294,7 @@ jobs:
permissions:
contents: write # Needed to push commit to update stable tag
pull-requests: write # Needed to create PR for VERSION update.
if: github.repository == 'argoproj/argo-cd'
if: github.repository == 'argoproj/argo-cd' || needs.setup-variables.outputs.allow_fork_release == 'true'
runs-on: ubuntu-22.04
env:
TAG_STABLE: ${{ needs.setup-variables.outputs.is_latest_release }}

View File

@@ -66,14 +66,14 @@ release:
```shell
kubectl create namespace argocd
kubectl apply -n argocd --server-side -f https://raw.githubusercontent.com/argoproj/argo-cd/{{.Tag}}/manifests/install.yaml
kubectl apply -n argocd --server-side -f https://raw.githubusercontent.com/{{ .Env.GORELEASER_CURRENT_REPOSITORY }}/{{.Tag}}/manifests/install.yaml
```
### HA:
```shell
kubectl create namespace argocd
kubectl apply -n argocd --server-side -f https://raw.githubusercontent.com/argoproj/argo-cd/{{.Tag}}/manifests/ha/install.yaml
kubectl apply -n argocd --server-side -f https://raw.githubusercontent.com/{{ .Env.GORELEASER_CURRENT_REPOSITORY }}/{{.Tag}}/manifests/ha/install.yaml
```
## Release Signatures and Provenance
@@ -87,7 +87,7 @@ release:
If upgrading from a different minor version, be sure to read the [upgrading](https://argo-cd.readthedocs.io/en/stable/operator-manual/upgrading/overview/) documentation.
footer: |
**Full Changelog**: https://github.com/argoproj/argo-cd/compare/{{ .PreviousTag }}...{{ .Tag }}
**Full Changelog**: https://github.com/{{ .Env.GORELEASER_CURRENT_REPOSITORY }}/compare/{{ .PreviousTag }}...{{ .Tag }}
<a href="https://argoproj.github.io/cd/"><img src="https://raw.githubusercontent.com/argoproj/argo-site/master/content/pages/cd/gitops-cd.png" width="25%" ></a>

View File

@@ -213,6 +213,10 @@ ifdef IMAGE_NAMESPACE
IMAGE_PREFIX=${IMAGE_NAMESPACE}/
endif
ifndef IMAGE_REGISTRY
IMAGE_REGISTRY="quay.io"
endif
.PHONY: all
all: cli image
@@ -308,12 +312,11 @@ endif
.PHONY: manifests-local
manifests-local:
./hack/update-manifests.sh
.PHONY: manifests
manifests: test-tools-image
$(call run-in-test-client,make manifests-local IMAGE_NAMESPACE='${IMAGE_NAMESPACE}' IMAGE_TAG='${IMAGE_TAG}')
$(call run-in-test-client,make manifests-local IMAGE_REGISTRY='${IMAGE_REGISTRY}' IMAGE_NAMESPACE='${IMAGE_NAMESPACE}' IMAGE_REPOSITORY='${IMAGE_REPOSITORY}' IMAGE_TAG='${IMAGE_TAG}')
# consolidated binary for cli, util, server, repo-server, controller
.PHONY: argocd-all
argocd-all: clean-debug
CGO_ENABLED=${CGO_FLAG} GOOS=${GOOS} GOARCH=${GOARCH} GODEBUG="tarinsecurepath=0,zipinsecurepath=0" go build -v -ldflags '${LDFLAGS}' -o ${DIST_DIR}/${BIN_NAME} ./cmd

View File

@@ -0,0 +1,49 @@
# Maintaining Internal Argo CD Forks
Most Argo CD contributors don't need this section to contribute to Argo CD. In most cases, the [Regular Developer Guide](index.md) is sufficient.
This section will help companies that need to publish custom Argo CD images or publish custom Argo CD releases from their forks.
Such companies need the below documentation in addition to the [Regular Developer Guide](index.md).
This section will also help Argo CD maintainers to test the release process in a test environment.
## Understanding where and which upstream images are published
Official upstream release tags (`vX.Y.Z*`) publish their multi-platform images and the corresponding provenance attestations—to `quay.io/argoproj/argocd` (or whatever registry a fork configures via `IMAGE_*` variables).
Upstream master builds continue to refresh the `latest` tag in the same primary registry, while also pushing commit-tagged images (and their provenance) to `ghcr.io/argoproj/argo-cd/argocd` so `cd.apps.argoproj.io` can pin exact SHAs.
Forks inherit the same behavior but target their customized registries/namespaces and do not deploy to `cd.apps.argoproj.io`.
## Publishing custom images from forked master branches
Fork builds can publish their own containers once workflow variables point at your registry/namespace instead of `argoproj`.
### Configuring GitHub Actions variables
Adjust the variables below to match your setup (overriding `IMAGE_NAMESPACE` is required, because it flips the workflows out of “upstream” mode):
- `IMAGE_NAMESPACE` defaults to `argoproj` (overriding required)
- `IMAGE_REPOSITORY` defaults to `argocd` (may need overriding)
- `GHCR_NAMESPACE` defaults to `${{ github.repository }}`, which translates to `<YOUR_GITHUB_USERNAME>/<YOUR_FORK_REPO>`, rarely needs overriding)
- `GHCR_REPOSITORY` defaults to `argocd` (may need overriding)
These values produce the final image names:
- `quay.io/$IMAGE_NAMESPACE/$IMAGE_REPOSITORY`
- `ghcr.io/$GHCR_NAMESPACE/$GHCR_REPOSITORY`
Example: if your GitHub account is `my-user`, your fork is `my-argo-cd-fork`, and you want to push release images to `quay.io/my-quay-user/argocd`, configure:
- `IMAGE_NAMESPACE = my-quay-user`
Your master build images will then be published to `quay.io/my-quay-user/argocd:latest`, and the commit tagged images along with the attestations will be published under the Packages (GHCR) of your GitHub fork repo.
### Configuring GitHub Actions secrets
Supply credentials for your primary registry so the workflow can push:
- `RELEASE_QUAY_USERNAME`
- `RELEASE_QUAY_TOKEN`
## Enabling fork releases
Forks can run the full release workflow by setting `ENABLE_FORK_RELEASES: true`, ensuring all upstream tags are fetched (the release tooling needs previous tags for changelog diffs), and reusing the same image variables/secrets listed above so release images push to your custom registry. After that, follow the standard [Release Process](releasing.md) with one critical adjustment:
> [!WARNING]
> When invoking `hack/trigger-release.sh`, point it at your fork remote (usually `origin`) rather than ~~upstream~~, otherwise the script may try to push official tags.
> Example: `./hack/trigger-release.sh v2.7.2 origin`

View File

@@ -71,6 +71,8 @@ Example:
./hack/trigger-release.sh v2.7.2 upstream
```
The script will ask for confirmation, type `y` to proceed. If no confirmation is received within 30 seconds, the script will abort.
> [!TIP]
> The tag must be in one of the following formats to trigger the GH workflow:<br>
> * GA: `v<MAJOR>.<MINOR>.<PATCH>`<br>

View File

@@ -199,6 +199,7 @@ docker login
You will need to push the built images to your own Docker namespace:
```bash
export IMAGE_REGISTRY=docker.io
export IMAGE_NAMESPACE=youraccount
```
@@ -223,7 +224,7 @@ DOCKER_PUSH=true make image
#### Configure manifests for your image
With `IMAGE_NAMESPACE` and `IMAGE_TAG` still set, run:
With `IMAGE_REGISTRY`, `IMAGE_NAMESPACE` and `IMAGE_TAG` still set, run:
```bash
make manifests
@@ -238,7 +239,7 @@ make manifests-local
(depending on your toolchain) to build a new set of installation manifests which include your specific image reference.
> [!NOTE]
> Do not commit these manifests to your repository. If you want to revert the changes, the easiest way is to unset `IMAGE_NAMESPACE` and `IMAGE_TAG` from your environment and run `make manifests` again. This will re-create the default manifests.
> Do not commit these manifests to your repository. If you want to revert the changes, the easiest way is to unset `IMAGE_REGISTRY`, `IMAGE_NAMESPACE` and `IMAGE_TAG` from your environment and run `make manifests` again. This will re-create the default manifests.
#### Configure your cluster with custom manifests

View File

@@ -31,6 +31,34 @@ fi
echo ">> Working in release branch '${RELEASE_BRANCH}'"
# Safety check: Warn if pushing to official argoproj/argo-cd repository
REMOTE_URL=$(git remote get-url "${GIT_REMOTE}")
if echo "${REMOTE_URL}" | grep -q "argoproj/argo-cd"; then
echo "" >&2
echo "!! ============================================================================" >&2
echo "!! WARNING: Remote '${GIT_REMOTE}' points to OFFICIAL argoproj/argo-cd!" >&2
echo "!! Remote URL: ${REMOTE_URL}" >&2
echo "!! ============================================================================" >&2
echo "!!" >&2
echo "!! This will create an OFFICIAL Argo CD release:" >&2
echo "!! - Tag: ${NEW_TAG}" >&2
echo "!! - Images: quay.io/argoproj/argocd:${NEW_TAG}" >&2
echo "!! - GitHub Release: https://github.com/argoproj/argo-cd/releases" >&2
echo "!! - Visible to ALL users" >&2
echo "!!" >&2
echo "!! If you want to release from YOUR FORK:" >&2
echo "!! 1. Press Ctrl+C now" >&2
echo "!! 2. Use your fork remote: ./hack/trigger-release.sh ${NEW_TAG} origin" >&2
echo "!!" >&2
echo "!! To proceed with OFFICIAL release, type 'y' (30 second timeout):" >&2
read -t 30 -r confirmation
if [ "$confirmation" != "y" ]; then
echo "!! Cancelled. Did not receive 'y' confirmation." >&2
exit 1
fi
echo ">> Confirmed official release. Proceeding..." >&2
fi
echo ">> Ensuring release branch is up to date."
# make sure release branch is up to date
git pull "${GIT_REMOTE}" "${RELEASE_BRANCH}"

View File

@@ -12,9 +12,36 @@ KUSTOMIZE=kustomize
cd "${SRCROOT}/manifests/ha/base/redis-ha" && ./generate.sh
IMAGE_NAMESPACE="${IMAGE_NAMESPACE:-quay.io/argoproj}"
# Image repository configuration - can be overridden in forks
IMAGE_REGISTRY="${IMAGE_REGISTRY:-quay.io}"
IMAGE_NAMESPACE="${IMAGE_NAMESPACE:-argoproj}"
IMAGE_REPOSITORY="${IMAGE_REPOSITORY:-argocd}"
IMAGE_TAG="${IMAGE_TAG:-}"
# Construct full image name
FULL_IMAGE_NAME="${IMAGE_REGISTRY}/${IMAGE_NAMESPACE}/${IMAGE_REPOSITORY}"
# Auto-detect current image in manifests for release workflows
detect_current_image() {
local manifest_file="$1"
if [ -f "$manifest_file" ]; then
# Look for the current image name in kustomization.yaml images section
awk '/^images:/,/^[a-zA-Z]/ { if (/- name:/ && /argocd/) { gsub(/.*name: */, ""); gsub(/ *$/, ""); print; exit } }' "$manifest_file"
fi
}
# Determine source image (what to replace)
DETECTED_IMAGE=$(detect_current_image "${SRCROOT}/manifests/base/kustomization.yaml")
if [ -n "$DETECTED_IMAGE" ] && [ "$DETECTED_IMAGE" != "quay.io/argoproj/argocd" ]; then
# Found a custom image in manifests (subsequent release scenario)
SOURCE_IMAGE_NAME="$DETECTED_IMAGE"
echo "Detected existing custom image in manifests: $SOURCE_IMAGE_NAME"
else
# Use default source image (fresh fork or manual override)
SOURCE_IMAGE_NAME="quay.io/argoproj/argocd"
echo "Using default source image: $SOURCE_IMAGE_NAME"
fi
# if the tag has not been declared, and we are on a release branch, use the VERSION file.
if [ "$IMAGE_TAG" = "" ]; then
branch=$(git rev-parse --abbrev-ref HEAD)
@@ -31,13 +58,23 @@ fi
$KUSTOMIZE version
which "$KUSTOMIZE"
cd "${SRCROOT}/manifests/base" && $KUSTOMIZE edit set image "quay.io/argoproj/argocd=${IMAGE_NAMESPACE}/argocd:${IMAGE_TAG}"
cd "${SRCROOT}/manifests/ha/base" && $KUSTOMIZE edit set image "quay.io/argoproj/argocd=${IMAGE_NAMESPACE}/argocd:${IMAGE_TAG}"
cd "${SRCROOT}/manifests/core-install" && $KUSTOMIZE edit set image "quay.io/argoproj/argocd=${IMAGE_NAMESPACE}/argocd:${IMAGE_TAG}"
echo "=== Manifest Generation Configuration ==="
echo "Source image (to replace): ${SOURCE_IMAGE_NAME}"
echo "Target image (replace with): ${FULL_IMAGE_NAME}:${IMAGE_TAG}"
if [ "$DETECTED_IMAGE" != "quay.io/argoproj/argocd" ] && [ -n "$DETECTED_IMAGE" ]; then
echo "Scenario: Subsequent release (updating existing custom image)"
else
echo "Scenario: First release or local development"
fi
echo "========================================"
cd "${SRCROOT}/manifests/base" && $KUSTOMIZE edit set image "${SOURCE_IMAGE_NAME}=${FULL_IMAGE_NAME}:${IMAGE_TAG}"
cd "${SRCROOT}/manifests/ha/base" && $KUSTOMIZE edit set image "${SOURCE_IMAGE_NAME}=${FULL_IMAGE_NAME}:${IMAGE_TAG}"
cd "${SRCROOT}/manifests/core-install" && $KUSTOMIZE edit set image "${SOURCE_IMAGE_NAME}=${FULL_IMAGE_NAME}:${IMAGE_TAG}"
# Because commit-server is added as a resource outside the base, we have to explicitly set the image override here.
# If/when commit-server is added to the base, this can be removed.
cd "${SRCROOT}/manifests/base/commit-server" && $KUSTOMIZE edit set image "quay.io/argoproj/argocd=${IMAGE_NAMESPACE}/argocd:${IMAGE_TAG}"
cd "${SRCROOT}/manifests/base/commit-server" && $KUSTOMIZE edit set image "${SOURCE_IMAGE_NAME}=${FULL_IMAGE_NAME}:${IMAGE_TAG}"
echo "${AUTOGENMSG}" > "${SRCROOT}/manifests/install.yaml"
$KUSTOMIZE build "${SRCROOT}/manifests/cluster-install" >> "${SRCROOT}/manifests/install.yaml"

View File

@@ -233,6 +233,7 @@ nav:
- developer-guide/faq.md
- developer-guide/tilt.md
- developer-guide/custom-resource-icons.md
- developer-guide/maintaining-internal-argo-cd-forks.md
- faq.md
- security_considerations.md
- Support: SUPPORT.md