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
26 changes: 6 additions & 20 deletions .github/workflows/docker-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@
# attached as an OCI artifact (oras attach) and the build-index pushed as a
# tagged OCI artifact under the `builds` project for downstream deploys.
#
# Artifactory push retired (Phase 5, DEVENV-9681). The legacy registry_*
# inputs / ARTIFACTORY_TOKEN secret are kept defined but no longer drive a
# push - they remain only so existing caller repos don't break, and so a
# Dockerfile can still pull an Artifactory base at build time via BAKE_SECRETS.
# Artifactory push retired (Phase 5, DEVENV-9681) and the server decommissioned
# (DEVENV-9847, 2026-09-11); the legacy registry_* inputs and ARTIFACTORY_TOKEN
# secret were removed under DEVENV-9849 (no caller used them).

name: Docker Build

Expand Down Expand Up @@ -40,16 +39,6 @@ on:
description: 'Push images to registry'
type: boolean
default: true
registry_host:
description: 'Legacy Artifactory hostname (no longer a push target; kept for caller compat / optional build-time base pulls)'
type: string
required: false
default: artifactory.landcareresearch.co.nz
registry_username:
description: 'Legacy Artifactory username (unused by the push; kept for caller compat)'
type: string
required: false
default: ''
runs_on:
description: 'Runner to use (ubuntu-latest for GitHub-hosted, tak-k8s-ci for self-hosted K8s)'
type: string
Expand All @@ -72,9 +61,6 @@ on:
type: string
default: ''
secrets:
ARTIFACTORY_TOKEN:
required: false
description: 'Legacy Artifactory identity token (no longer used for the push; optional build secret via BAKE_SECRETS)'
BAKE_SECRETS:
required: false
description: 'Build secrets in docker secret format'
Expand Down Expand Up @@ -125,7 +111,7 @@ jobs:
fi

# Push target is now prod Harbor: ${harbor_host}/${namespace}/${image}
# (the project == namespace; no Artifactory `/docker/` path segment).
# (the project == namespace).
REGISTRY_PREFIX="${{ inputs.harbor_host }}/${{ inputs.image_namespace }}/${IMAGE_NAME}"

echo "build_id=${BUILD_ID}" >> $GITHUB_OUTPUT
Expand Down Expand Up @@ -387,7 +373,7 @@ jobs:
done

# Build index as a tagged OCI artifact under the builds project - the
# Harbor home of what was the Artifactory build-index.json. Path
# Path
# contract: builds/<image_name>:<build_id> (no namespace) - matches
# docker-build-pipe run.sh + k8s-apps-config update-app-manifest.sh.
harbor_build_index_ref="${HARBOR_HOST}/${HARBOR_BUILDS_PROJECT:-builds}/${IMAGE_NAME}:${BUILD_ID}"
Expand All @@ -396,7 +382,7 @@ jobs:
# Bitbucket docker-build-pipe use the blob names outputs.json /
# bake-metadata.json; oras uses the filename as the blob title, so push
# under those names or a GitHub-built index is invisible to the deploy
# step (it checks for outputs.json) and falls back to retired Artifactory.
# step (it checks for outputs.json).
cp build-index.json outputs.json
cp bake.json bake-metadata.json
oras push \
Expand Down
22 changes: 10 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Reusable GitHub Actions workflows for building Docker images with secure GitOps

```
┌─────────────────────┐ ┌─────────────────────┐
│ GitHub Repo │ │ Artifactory │
│ GitHub Repo │ │ Harbor │
│ (source code) │────►│ (container images) │
│ │ │ │
│ • Builds images │ └──────────┬──────────┘
Expand Down Expand Up @@ -51,7 +51,7 @@ Reusable GitHub Actions workflows for building Docker images with secure GitOps

### docker-build.yml

Builds Docker images using `docker buildx bake`, pushes to Artifactory, and uploads build metadata.
Builds Docker images using `docker buildx bake`, pushes them to Harbor (`registry.landcareresearch.co.nz`) and pushes the build index as an OCI artifact. Harbor is internal-only, so builds run on the self-hosted `tak-k8s-ci` runner.

```yaml
jobs:
Expand All @@ -60,10 +60,10 @@ jobs:
with:
bake_file: docker-bake.hcl
bake_target: default
harbor_username: robot$github-builder
runs_on: tak-k8s-ci
secrets:
ARTIFACTORY_HOST: ${{ secrets.ARTIFACTORY_HOST }}
ARTIFACTORY_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
ARTIFACTORY_TOKEN: ${{ secrets.ARTIFACTORY_TOKEN }}
HARBOR_TOKEN: ${{ secrets.HARBOR_TOKEN }}
```

**Outputs:**
Expand Down Expand Up @@ -98,9 +98,7 @@ Configure these secrets in your GitHub organization or repository:

| Secret | Description |
|--------|-------------|
| `ARTIFACTORY_HOST` | Artifactory hostname (e.g., `artifactory.landcareresearch.co.nz`) |
| `ARTIFACTORY_USERNAME` | Artifactory username |
| `ARTIFACTORY_TOKEN` | Artifactory identity token |
| `HARBOR_TOKEN` | Token for the Harbor push robot named in the `harbor_username` input (e.g. `robot$github-builder`) |

**Note:** No GitOps credentials needed! Image Updater handles deployment.

Expand Down Expand Up @@ -138,7 +136,7 @@ metadata:
name: dev-my-app
annotations:
argocd-image-updater.argoproj.io/image-list: |
app=artifactory.landcareresearch.co.nz/docker/mwlr-private/my-app/app
app=registry.landcareresearch.co.nz/mwlr-private/my-app/app
argocd-image-updater.argoproj.io/app.update-strategy: newest-build
argocd-image-updater.argoproj.io/app.allow-tags: "regexp:^[0-9]+-[a-f0-9]+$"
argocd-image-updater.argoproj.io/write-back-method: git
Expand Down Expand Up @@ -177,10 +175,10 @@ jobs:
bake_file: docker-bake.hcl
bake_target: default
push: ${{ github.event_name != 'pull_request' }}
harbor_username: robot$github-builder
runs_on: tak-k8s-ci
secrets:
ARTIFACTORY_HOST: ${{ secrets.ARTIFACTORY_HOST }}
ARTIFACTORY_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
ARTIFACTORY_TOKEN: ${{ secrets.ARTIFACTORY_TOKEN }}
HARBOR_TOKEN: ${{ secrets.HARBOR_TOKEN }}

summary:
needs: build
Expand Down
12 changes: 5 additions & 7 deletions examples/barcode-data-portal/ci.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
# CI/CD workflow for barcode-data-portal-mwlr
#
# Security Model:
# - CI builds and pushes images to Artifactory
# - CI builds and pushes images to Harbor (registry.landcareresearch.co.nz)
# - ArgoCD Image Updater automatically deploys to dev
# - NO GitOps repo access from CI
#
# Required secrets:
# - ARTIFACTORY_HOST
# - ARTIFACTORY_USERNAME
# - ARTIFACTORY_TOKEN
# - HARBOR_TOKEN (token for the robot named in harbor_username)

name: CI/CD

Expand All @@ -25,10 +23,10 @@ jobs:
bake_file: docker-bake.hcl
bake_target: default
push: ${{ github.event_name != 'pull_request' }}
harbor_username: robot$github-builder
runs_on: tak-k8s-ci
secrets:
ARTIFACTORY_HOST: ${{ secrets.ARTIFACTORY_HOST }}
ARTIFACTORY_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
ARTIFACTORY_TOKEN: ${{ secrets.ARTIFACTORY_TOKEN }}
HARBOR_TOKEN: ${{ secrets.HARBOR_TOKEN }}

summary:
needs: build
Expand Down
7 changes: 3 additions & 4 deletions examples/consumer-workflow.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Example: Complete CI/CD workflow for a consumer repository
#
# Security Model:
# - CI builds and pushes images to Artifactory
# - CI builds and pushes images to Harbor (registry.landcareresearch.co.nz)
# - Deploy step triggers k8s-apps-config pipeline (no direct GitOps write access)
# - k8s-apps-config validates request and commits/creates PR
# - Nonprod: direct commit to main
Expand Down Expand Up @@ -34,10 +34,9 @@ jobs:
runs_on: tak-k8s-ci
# Only push on main branch, not PRs
push: ${{ github.event_name != 'pull_request' }}
registry_host: ${{ vars.ARTIFACTORY_HOST }}
registry_username: ${{ vars.ARTIFACTORY_USERNAME }}
harbor_username: robot$github-builder
secrets:
ARTIFACTORY_TOKEN: ${{ secrets.ARTIFACTORY_TOKEN }}
HARBOR_TOKEN: ${{ secrets.HARBOR_TOKEN }}

# Deploy to dev (automatic)
deploy-dev:
Expand Down
4 changes: 2 additions & 2 deletions examples/docker-bake.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

// Variables provided by the build workflow
variable "REGISTRY_PREFIX" {
description = "Registry path prefix (e.g., artifactory.example.com/docker/mwlr-private/my-app)"
description = "Registry path prefix (e.g., registry.landcareresearch.co.nz/mwlr-private/my-app)"
}

variable "IMAGE_TAG" {
Expand Down Expand Up @@ -54,7 +54,7 @@ target "worker" {
// Example: Build with secrets (e.g., private package registry)
// target "app-with-secrets" {
// inherits = ["app"]
// secret = ["type=env,id=ARTIFACTORY_TOKEN"]
// secret = ["type=env,id=GITHUB_PACKAGES_READ_TOKEN"]
// }

// Example: Multi-stage build with different context
Expand Down
Loading