Skip to content

Add Cloud Build recipe (cloudbuild-gcr.yaml) for gcr.io/cdapio/cdap-controller; retire previous nightly 'latest' - #175

Closed
HarshitJain09 wants to merge 2 commits into
developfrom
harshkjn/gcr-nightly-retire-previous
Closed

HarshitJain09 wants to merge 2 commits into
developfrom
harshkjn/gcr-nightly-retire-previous

Conversation

@HarshitJain09

@HarshitJain09 HarshitJain09 commented Nov 3, 2026 •

Copy link
Copy Markdown

What

Moves the Cloud Build recipe for the gcr.io/cdapio/cdap-controller image out of the Cloud Source Repositories repo cdap-oss-build (CSR is End-of-Sale, and that repo has no PR/review gate) into this repository as cloudbuild-gcr.yaml, so the build recipe is reviewed in the same place as the Dockerfile it builds. Adds a short README section documenting the trigger ↔ file mapping.

The same file serves both triggers in project cdapio: cdap-controller-docker-nightly (daily latest from develop) and cdap-controller-docker (release builds, run with _VERSION overridden).

Companion PR for the other image built from cdap-oss-build: cdapio/cdap-build#578.

Why

Nightly rebuilds of latest leave the previous digest untagged-but-scanned, so vulnerability scanning keeps filing new findings against stale images. After this change the nightly build tags the previous latest digest with no-new-use-public-image-<sha256> right after the new latest is pushed, which marks it as superseded for scanning.

Why the recipe moves to GitHub instead of being edited in CSR

  • Cloud Source Repositories has not been available to new customers since 2024-06-17 and has an announced future shutdown; all repositories must be migrated before then (https://cloud.google.com/source-repositories/docs/migration-guides).
  • Google Cloud's migration guidance for the exact shape of cdap-oss-build ("a mirror of an external repository used to trigger Cloud Build") is to connect Cloud Build directly to the source repository rather than keep a wrapper repo in CSR (https://cloud.google.com/build/docs/automating-builds/github/connect-repo-github).
  • Project cdapio already has a GitHub-connected Cloud Build trigger (cdap-ui-tests -> cdapio/cdap), so this extends an existing pattern rather than introducing a new integration.
  • Keeping the recipe here means it is reviewed in the same PR flow, on the same protected develop branch, as the Dockerfile it builds.
  • Retiring the previous image immediately after the replacement is published, inside the same build, is the usual way public image registries stop scanners from re-reporting superseded images. The same tag logic has been applied by hand to 59 superseded cdap / cdap-controller digests since 2025-10-30 with no failures; this PR makes the nightly do it itself.

Behaviour vs. the current CSR cloudbuild-operator.yaml

Step Before (CSR) After (this file)
record previous ${_VERSION} digest – new (record-previous), nightly builds only
git clone … cdap-operator -b ${BRANCH_NAME} needed because the config lived in another repo dropped — the trigger checks this repo out itself (no submodules here)
docker build -t gcr.io/cdapio/cdap-controller:${_VERSION} . in cdap-operator/ in the workspace root
push implicit via images: after all steps explicit docker push so the next step provably runs after the image exists (images: kept, harmless)
retire previous latest – new (tag-previous-latest), no-op unless _VERSION == latest

Safety properties of the retire step

  • Release builds (_VERSION ≠ latest) never retire anything, and make no registry lookups.
  • Build or push fails → step never runs → nothing changes.
  • No previous latest (first run) → no-op, and no registry lookup is made.
  • Rebuild produced the identical digest → refuses to tag the live image.
  • _TAG_PREVIOUS=false → prints what it would do, tags nothing.
  • Only ever adds one tag to one digest; nothing is deleted. Rollback: gcloud container images untag.

Dry run (from a checkout of this branch)

gcloud builds submit --project=cdapio --config=cloudbuild-gcr.yaml \
    --substitutions=_TAG_PREVIOUS=false .

Rollout plan (staged; every step reversible)

All CSR-backed Cloud Build triggers in project cdapio, and where each moves:

Trigger Today Plan
cdap-controller-docker-nightly (daily latest) CSR cloudbuild-operator.yaml Phase 1a -> cdap-operator cloudbuild-gcr.yaml (this PR)
cdap-docker (daily latest) CSR cloudbuild.yaml Phase 1b -> cdap-build cloudbuild-gcr.yaml (cdapio/cdap-build#578)
cdap-controller-docker (release, manual _VERSION) CSR cloudbuild-operator.yaml after nightlies are stable -> same file as this PR (retire step is a no-op for releases)
cdap-maven-docker-build (weekly) CSR cloudbuild-maven.yaml Phase 2, separate PR (no retire step needed)
  1. Merge this PR — the file is inert until a trigger points at it.
  2. Dry run from develop with _TAG_PREVIOUS=false; confirm it builds, pushes and prints the digest it would retire.
  3. Repoint cdap-controller-docker-nightly (one trigger field, same trigger ID, Cloud Scheduler untouched) from CSR cdap-oss-build/cloudbuild-operator.yaml to GitHub cdapio/cdap-operator @ ^develop$ / cloudbuild-gcr.yaml; watch one nightly.
  4. Repoint cdap-docker the same way (see Add Cloud Build recipe (cloudbuild-gcr.yaml) for nightly gcr.io/cdapio/cdap; retire previous 'latest' cdap-build#578 for its Cloud Scheduler body change).
  5. Phase 2: move cdap-maven-docker-build, then the release trigger cdap-controller-docker (same file, same one-field change); delete the CSR files after a clean week.

Worst case at any step is "no nightly today" (same as an ordinary build failure). The retire step only ever adds one tag to one digest; the live latest is never touched and nothing is deleted. Rollback of a repoint is a one-field change back to CSR; rollback of a tag is gcloud container images untag. Before/after trigger exports will be recorded on the internal tracking bug.

Review notes

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new Cloud Build configuration (cloudbuild-gcr.yaml) to automate building and pushing the cdap-controller Docker image, along with a mechanism to tag and retire superseded nightly images to stop vulnerability scanning on stale builds. The README.md has also been updated to document this process. The review feedback suggests optimizing the build steps by wrapping the gcloud image description queries in conditional checks, ensuring they only run when necessary (e.g., for nightly builds) and avoiding potential failures or redundant API calls when no previous image exists.

Comment thread cloudbuild-gcr.yaml Resolved
Comment thread cloudbuild-gcr.yaml Resolved
…ontroller; retire previous nightly 'latest'

Moves the Cloud Build configuration for the gcr.io/cdapio/cdap-controller
image out of the Cloud Source Repositories repo `cdap-oss-build` (End of Sale,
no review gate) into this repository as `cloudbuild-gcr.yaml`, so the build
recipe is reviewed alongside the Dockerfile it builds. The same file serves
the nightly `latest` build and manual release builds (`_VERSION=<release>`).

Behavioural change vs. the CSR recipe: after a new nightly `latest` is pushed,
the digest that was previously `latest` is tagged
`no-new-use-public-image-<sha256>`, so vulnerability scanning stops filing new
findings against superseded nightly images. Guards: no-op when `_VERSION` is
not `latest`, when there is no previous `latest`, or when the digest did not
change; `_TAG_PREVIOUS=false` gives a dry run.
@HarshitJain09
HarshitJain09 force-pushed the harshkjn/gcr-nightly-retire-previous branch from 4b4e983 to d041c3c Compare November 3, 2026 05:46
* record-previous: only query the registry for the previous digest on
  nightly (_VERSION=latest) builds. Release builds never retire anything,
  so the lookup was a wasted call; the step now matches its own comment.
* tag-previous-latest: check for a previous digest *before* describing the
  new `latest`. With `set -euo pipefail`, a transient lookup failure could
  previously fail a first-ever run that had nothing to retire.

No behaviour change when a previous digest exists: the lookup still runs
and a failure there still fails the build loudly (intended - the image is
already pushed and a red build is the signal that the retire did not
happen).
HarshitJain09 added a commit to cdapio/cdap-build that referenced this pull request Nov 3, 2026
tag-previous-latest now checks for a previous `latest` digest *before*
describing the new one. With `set -euo pipefail`, a transient lookup
failure could previously fail a first-ever run that had nothing to retire.
Mirrors the same change in the cdap-operator recipe
(cdapio/cdap-operator#175).

No behaviour change when a previous digest exists: the lookup still runs
and a failure there still fails the build loudly (intended - the image is
already pushed and a red build is the signal that the retire did not
happen).
@HarshitJain09

Copy link
Copy Markdown
Author

Closing — landed directly in the Cloud Build trigger configuration repository for now.

@HarshitJain09
HarshitJain09 deleted the harshkjn/gcr-nightly-retire-previous branch November 3, 2026 11:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant