6.2 Promote to prod repo

Overview

You commit the same signed digest to a second Gitea remote (student_prod_gitops_repo_url points at lw-student/gitops-prod-spring-boot-lw-poc). Production is not a second Helm file in the stage repo. The seed digest is sha256:REPLACE_ME_PROD_DIGEST, replicas start at 0, and there is no TrustPolicy on the prod tree. Admission already landed on lw-poc-prod from 6.1.

The Check fails if Application lw-poc-prod still tracks the stage remote.

Why it matters

Production is a deliberate git commit to production desired state. It is not retargeting Argo at stage. ImagePolicy from 6.1 still holds. The digest is the one you signed.

You clone the prod remote and cosign copy onto the prod ImageStream because oc tag still does not copy .sig tags. Konflux Release Service maps to this commit.

Lightwell Network and Clearinghouse Premier do not change the promote remote. The GAV is already inside the digest.

What does it solve

  • Production that is not a separate digest-pinned promote

  • Pointing prod Argo at stage

  • A second Helm file in the stage repo

Why two remotes

Stage versus prod Gitea remotes — promotion is a commit to the second remote

Konflux Release Service maps to this commit (Konflux mapping). Do not “fix” a broken prod app by pointing Argo at stage.

Worked example (not the Check)

Stage values.yaml / PROMOTE.md, or retarget Argo at the stage remote. Paste-identical copy fails.

# Worked example ONLY — still the seed; do not copy this onto the prod remote.
image:
  digest: sha256:REPLACE_ME_PROD_DIGEST
replicas: 0
# Also not the Check: point Application lw-poc-prod at gitops-spring-boot-lw-poc (stage).

Your change: prod tag + prod commit

BUILD_NS="$(oc -n gitea get configmap demo-userinfo-gitea -o jsonpath='{.data.student_build_namespace}')"
PROD_NS="$(oc -n gitea get configmap demo-userinfo-gitea -o jsonpath='{.data.student_prod_namespace}')"
PROD_GITOPS="$(oc -n gitea get configmap demo-userinfo-gitea -o jsonpath='{.data.student_prod_gitops_repo_url}')"
echo "PROD_NS=${PROD_NS}"
echo "PROD_GITOPS=${PROD_GITOPS}"
oc tag "${BUILD_NS}/spring-boot-lw-poc:latest" "${PROD_NS}/spring-boot-lw-poc:latest"
oc -n "${PROD_NS}" get istag spring-boot-lw-poc:latest \
  -o jsonpath='{.image.metadata.name}{"\n"}'
DIGEST="$(oc -n "${PROD_NS}" get istag spring-boot-lw-poc:latest \
  -o jsonpath='{.image.metadata.name}')"
SRC="image-registry.openshift-image-registry.svc:5000/${BUILD_NS}/spring-boot-lw-poc@${DIGEST}"
DST="image-registry.openshift-image-registry.svc:5000/${PROD_NS}/spring-boot-lw-poc@${DIGEST}"
export HOME=/tmp/lab-home
mkdir -p "${HOME}"
cosign login -u unused -p "$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
  image-registry.openshift-image-registry.svc:5000
cosign copy --allow-http-registry --allow-insecure-registry "${SRC}" "${DST}"
COSIGN_PASSWORD="" cosign sign --key /home/lab-user/lab-trust/cosign.key \
  --tlog-upload=false --allow-http-registry --allow-insecure-registry \
  "${DST}"

Clone student_prod_gitops_repo_url (password is the value of ConfigMap key student_password — do not commit it). Set repo-local git config user.name / user.email (same as 6.1 — a fresh clone does not inherit the app-repo author). Replace sha256:REPLACE_ME_PROD_DIGEST with that digest; set replicas: 1. Commit and push this remote only. Do not copy values.yaml or PROMOTE.md from the stage clone.

PROD_GITOPS="$(oc -n gitea get configmap demo-userinfo-gitea -o jsonpath='{.data.student_prod_gitops_repo_url}')"
: "${STUDENT_USER:=$(oc -n gitea get configmap demo-userinfo-gitea -o jsonpath='{.data.student_username}')}"
: "${STUDENT_PASS:=$(oc -n gitea get configmap demo-userinfo-gitea -o jsonpath='{.data.student_password}')}"
rm -rf /tmp/gitops-prod
hostpath="${PROD_GITOPS#https://}"; hostpath="${hostpath#http://}"
git clone "https://${STUDENT_USER}:${STUDENT_PASS}@${hostpath}" /tmp/gitops-prod
cd /tmp/gitops-prod
git config user.name student
git config user.email student@workshop.local

Check: prod Application sources prod

PROD_GITOPS="$(oc -n gitea get configmap demo-userinfo-gitea -o jsonpath='{.data.student_prod_gitops_repo_url}')"
# Same as 6.1: push alone may not sync. Hard-refresh after replicas: 1 is on the prod remote.
oc -n openshift-gitops annotate applications.argoproj.io lw-poc-prod \
  argocd.argoproj.io/refresh=hard --overwrite
oc -n openshift-gitops get applications.argoproj.io lw-poc-prod \
  -o jsonpath='repo={.spec.source.repoURL}{"\n"}sync={.status.sync.status}{"\n"}health={.status.health.status}{"\n"}'
oc -n openshift-gitops get applications.argoproj.io lw-poc-prod \
  -o jsonpath='{.spec.source.repoURL}{"\n"}' | grep -F 'gitops-prod-spring-boot-lw-poc' \
  && echo 'prod remote OK' || echo 'STILL TRACKING STAGE OR WRONG REPO'
echo "expected prefix ${PROD_GITOPS}"
oc -n lw-poc-prod get deploy,pods,route,imagepolicy

Pass when:

  • lw-poc-prod .spec.source.repoURL is student_prod_gitops_repo_url (contains gitops-prod-spring-boot-lw-poc, not gitops-spring-boot-lw-poc.git without -prod-)

  • Application is Synced / Healthy on the signed digest (REPLACE_ME_PROD_DIGEST gone)

  • ImagePolicy from 6.1 is still present; unsigned still denied

Argo Application lw-poc-prod after 6.2: Synced and Healthy on the signed digest
Fill the report

The Job also grades ConfigMap report-16-prod-gitops key how_promote. Set it to prod-remote. Empty or REPLACE_ME fails even if cluster state is correct. Do not copy validate-docs.

oc -n lw-poc-validate edit configmap report-16-prod-gitops

The scored Check is Job validate-16-prod-gitops in lw-poc-validate. Direct nav URLs still work (honor system). Unlimited retries. There is no Solve.

Run the Validate Job
oc -n lw-poc-validate delete job validate-16-prod-gitops --ignore-not-found
TPL='job-16.yaml'
oc -n lw-poc-validate get configmap validate-job-templates \
  -o go-template="{{ index .data \"${TPL}\" }}" | oc create -f -
oc -n lw-poc-validate logs -f job/validate-16-prod-gitops

Expect CHECK PASSED: before you continue. CHECK FAILED: names the object to fix. Delete the Job and create it again as often as you need.

Continue to Track 7 when you are ready.

Official documentation

Key takeaways

  • Promotion is a git commit to a second remote, not a second values file and not retargeting prod Argo at stage.

  • Lightwell Network and Clearinghouse Premier ride inside the digest. They are not a different promote button.

cd ~/ocp5-rhacs-showroom
bash setup/lab-cleanup.sh --module tssc-16