From 09df906cd92563f6ac1f72ea086f4795fce92f48 Mon Sep 17 00:00:00 2001 From: kk640244 <219095469+kk640244@users.noreply.github.com> Date: Tue, 8 Sep 2026 14:32:26 +0530 Subject: [PATCH 01/11] Relocate chart-publish Jenkinsfile off gh-pages (Phase 1) gh-pages is being retired as part of the CAAPIM->Broadcom / GH Actions-> Jenkins migration. The chart-publish pipeline (push charts to Artifactory as OCI artifacts) currently lives only on the gh-pages branch, so it needs a permanent home before that branch is deleted. Pure relocation, byte-identical to origin/gh-pages:Jenkinsfile and origin/gh-pages:push_helm_charts.py - no logic changes yet. Adapting this to build the chart from the workspace instead of downloading a GitHub Release asset is a separate, later step. Still needed (outside this repo, not part of this commit): - Re-point the internal Jenkins job that currently reads Jenkinsfile from gh-pages to read Jenkinsfile-charts from this branch instead. Co-Authored-By: Claude Sonnet 5 --- Jenkinsfile-charts | 19 +++++++++++++++ push_helm_charts.py | 58 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 Jenkinsfile-charts create mode 100644 push_helm_charts.py diff --git a/Jenkinsfile-charts b/Jenkinsfile-charts new file mode 100644 index 00000000..92e477a1 --- /dev/null +++ b/Jenkinsfile-charts @@ -0,0 +1,19 @@ +pipeline { + agent { label 'default' } + options { + timeout(time: 15, unit: 'MINUTES') + } + environment { + ARTIFACTORY_CREDS = credentials("ARTIFACTORY_USERNAME_TOKEN") + GITHUB_CREDS = credentials("GITHUB_CAAPIM_TOKEN") + GITHUB_TOKEN = "${GITHUB_CREDS_PSW}" + } + stages { + stage('Push Helm Charts') { + steps { + sh("pip3 install requests ruamel.yaml") + sh("python3 push_helm_charts.py --release") + } + } + } +} diff --git a/push_helm_charts.py b/push_helm_charts.py new file mode 100644 index 00000000..4dab41e1 --- /dev/null +++ b/push_helm_charts.py @@ -0,0 +1,58 @@ +# Download latest released apim helm charts from github.com and push to artifactory +# +# Pre-requisite: +# - The gh-pages index.yaml file available +# - Artifactory credentials set in environment: ARTIFACTORY_CREDS_USR, ARTIFACTORY_CREDS_PSW +# - GitHub access token set in environment: GITHUB_TOKEN +# +# command examples: +# python3 push_helm_charts.py --index index.yaml + +import argparse +import os +import requests +import subprocess +from pathlib import Path +from ruamel.yaml import YAML + +parser = argparse.ArgumentParser(description='Push apim helm charts to artifactory') +parser.add_argument('--index', default='index.yaml', help='index file to read for chart releases') +parser.add_argument('--release', action='store_true', help='flag to push to release repo instead of dev') + +args = parser.parse_args() +username = os.getenv('ARTIFACTORY_CREDS_USR') +password = os.getenv('ARTIFACTORY_CREDS_PSW') +token = os.getenv('GITHUB_TOKEN') +if not username or not password or not token: + sys.exit("please set env for ARTIFACTORY_CREDS_USR, ARTIFACTORY_CREDS_PSW, and GITHUB_TOKEN") +helm_stage = "release" if args.release else "dev" +helm_repo = f"apim-docker-{helm_stage}-local.usw1.packages.broadcom.com" +subprocess.run(['docker', 'login', helm_repo, '-u', username, '-p', password], check=True, text=True) + +def download_chart(url): + local_filename = url.split("/")[-1] + headers = {'Authorization': f"Bearer {token}", 'Accept': 'application/vnd.github+json'} + + # download file + with requests.get(url, stream=True, headers=headers) as r: + r.raise_for_status() + with open(local_filename, 'wb') as f: + for chunk in r.iter_content(chunk_size=32768): + f.write(chunk) + print(f"downloaded {local_filename}") + return local_filename + +def main(): + path = Path(args.index) + yaml = YAML(typ='safe') + data = yaml.load(path) + operator_url = data["entries"]["layer7-operator"][0]["urls"][0] + + print(f"working on operator: {operator_url}") + operator_chart = download_chart(operator_url) + subprocess.run(['helm', 'push', operator_chart, f"oci://{helm_repo}"], check=True, text=True) + + subprocess.run(['docker', 'logout', helm_repo], check=True, text=True) + +if __name__ == "__main__": + main() From 3b92962994b0ab8bc9c601b986a1f2d71d3a74c2 Mon Sep 17 00:00:00 2001 From: kk640244 <219095469+kk640244@users.noreply.github.com> Date: Tue, 8 Sep 2026 16:37:38 +0530 Subject: [PATCH 02/11] Add PR-gated Test Automation stage to root Jenkinsfile (Phase 2a) Wires the existing, already-working layer7-operator-test-automation pipeline (job L7Operator/Components/L7Operator Test Automation/develop) into PR builds, gating merge status on its result. - Runs only on PR builds (env.CHANGE_ID) - a full regression run takes ~15min and spins up a kind cluster, not worth it on every branch push. - Passes OPERATOR_REF=env.CHANGE_BRANCH so the harness tests the PR's actual proposed source, not just whatever main/develop already is. - No separate chart-lint stage added here: layer7-operator-test-automation's own "Lint & scan" stage already runs `ct lint` (blocking when charts changed) plus warn-only golangci-lint/govulncheck - confirmed via a real console log (job Operator_Test_Automation_develop, 2026-08-27 run, passed=226 failed=0). Adding another lint stage here would duplicate it. - Relies on `build job:`'s default propagate:true: if the downstream run doesn't succeed, this stage throws and this build fails too, which the existing post{failure{pullRequest.createStatus(...)}} block already reports back to GitHub - no new status-reporting mechanism needed. - Left an explicit NOTE in the stage: this passes OPERATOR_REF only, so the harness rebuilds the operator image from source independently rather than consuming the image the "Build and Push Image" stage above just pushed. layer7-operator-test-automation's own PLAN.md already tracks that gap as a planned, opt-in USE_UPSTREAM_BUILD mode (default off) - revisit this call once that lands, to avoid the double build. Still needed (Jenkins job config, not a repo commit - tracked in the migration plan): add a real GitHub-webhook PR trigger to the Build L7Operator multibranch job for develop/main, since it currently only builds on branch-indexing/daily cron rather than firing live on PRs. Co-Authored-By: Claude Sonnet 5 --- Jenkinsfile | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/Jenkinsfile b/Jenkinsfile index b9644a70..4c939e18 100755 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -70,6 +70,30 @@ pipeline { } } } + stage('Test Automation') { + // Only run on PR builds - a full regression run takes ~15min and + // spins up a kind cluster, not worth it on every branch push. + when { expression { env.CHANGE_ID } } + steps { + script { + // NOTE: this only passes OPERATOR_REF (the PR's source branch), so + // layer7-operator-test-automation tests the right source code - but + // it independently rebuilds the operator image from that source + // rather than consuming the image just built/pushed by the + // "Build and Push Image" stage above. layer7-operator-test-automation's + // own PLAN.md already tracks this gap as a planned, opt-in + // USE_UPSTREAM_BUILD mode (default off) to consume this pipeline's + // published image instead of rebuilding. Revisit this call once + // that's implemented, to avoid the double build. + def testRun = build job: 'L7Operator/Components/L7Operator Test Automation/develop', + parameters: [ + string(name: 'OPERATOR_REF', value: env.CHANGE_BRANCH) + ], + wait: true + echo "layer7-operator-test-automation run: ${testRun.absoluteUrl} (${testRun.result})" + } + } + } } post { From c943be722fd33d6497c08fea7423bf019daf49e1 Mon Sep 17 00:00:00 2001 From: kk640244 <219095469+kk640244@users.noreply.github.com> Date: Tue, 8 Sep 2026 17:02:56 +0530 Subject: [PATCH 03/11] Adapt chart-publish pipeline to build from workspace, not GH Releases (Phase 2b) push_helm_charts.py no longer downloads a pre-built chart tarball from a GitHub Release (that source disappears once GH Actions/Releases are removed) - it now `helm package`s charts/layer7-operator directly from the checked-out workspace, then pushes the result as before. Dropped the now-unneeded GitHub API download path (requests/ruamel.yaml, GITHUB_TOKEN) entirely, and the --index argument that went with it. Also fixed a pre-existing bug: the old script called sys.exit(...) without importing sys. Jenkinsfile-charts is now branch-aware instead of hardcoding --release: - PR branches -> dev-local only (usw1 Artifactory already blocks promoting dev-local to layer7.packages.broadcom.com, so there's nothing further to do for a PR build). - main -> release-local (a separate, not-yet-built workflow will later promote this to layer7.packages.broadcom.com - Phase 2c). - any other branch -> skipped. Also dropped the GITHUB_CREDS/GITHUB_TOKEN env and the `pip3 install requests ruamel.yaml` step, both unused now. Still needed (Jenkins job config, not a repo commit - tracked in the migration plan): convert helm-github-to-release-operator from a standalone job into a multibranch job, so env.CHANGE_ID/BRANCH_NAME are actually populated per PR/branch the way this script now expects. Co-Authored-By: Claude Sonnet 5 --- Jenkinsfile-charts | 20 ++++++++++++++----- push_helm_charts.py | 48 ++++++++++++++++----------------------------- 2 files changed, 32 insertions(+), 36 deletions(-) diff --git a/Jenkinsfile-charts b/Jenkinsfile-charts index 92e477a1..716a7905 100644 --- a/Jenkinsfile-charts +++ b/Jenkinsfile-charts @@ -5,14 +5,24 @@ pipeline { } environment { ARTIFACTORY_CREDS = credentials("ARTIFACTORY_USERNAME_TOKEN") - GITHUB_CREDS = credentials("GITHUB_CAAPIM_TOKEN") - GITHUB_TOKEN = "${GITHUB_CREDS_PSW}" } stages { - stage('Push Helm Charts') { + stage('Push Helm Chart') { steps { - sh("pip3 install requests ruamel.yaml") - sh("python3 push_helm_charts.py --release") + script { + // PR branches only ever push to dev-local (usw1 Artifactory blocks + // promoting dev-local to layer7.packages.broadcom.com, so there's + // nothing further to do for a PR build). The default branch pushes + // to release-local, which a separate, not-yet-built workflow later + // promotes to layer7.packages.broadcom.com (Phase 2c). + if (env.CHANGE_ID) { + sh 'python3 push_helm_charts.py' + } else if (env.BRANCH_NAME == 'main') { + sh 'python3 push_helm_charts.py --release' + } else { + echo "not a PR and not main - skipping chart publish for branch ${env.BRANCH_NAME}" + } + } } } } diff --git a/push_helm_charts.py b/push_helm_charts.py index 4dab41e1..96d9fbef 100644 --- a/push_helm_charts.py +++ b/push_helm_charts.py @@ -1,55 +1,41 @@ -# Download latest released apim helm charts from github.com and push to artifactory +# Package the layer7-operator helm chart from this workspace and push it to +# Artifactory as an OCI artifact. # # Pre-requisite: -# - The gh-pages index.yaml file available # - Artifactory credentials set in environment: ARTIFACTORY_CREDS_USR, ARTIFACTORY_CREDS_PSW -# - GitHub access token set in environment: GITHUB_TOKEN # # command examples: -# python3 push_helm_charts.py --index index.yaml +# python3 push_helm_charts.py +# python3 push_helm_charts.py --release +# python3 push_helm_charts.py --chart-dir charts/layer7-operator import argparse import os -import requests import subprocess -from pathlib import Path -from ruamel.yaml import YAML +import sys -parser = argparse.ArgumentParser(description='Push apim helm charts to artifactory') -parser.add_argument('--index', default='index.yaml', help='index file to read for chart releases') +parser = argparse.ArgumentParser(description='Package and push the layer7-operator helm chart to artifactory') +parser.add_argument('--chart-dir', default='charts/layer7-operator', help='path to the chart to package') parser.add_argument('--release', action='store_true', help='flag to push to release repo instead of dev') args = parser.parse_args() username = os.getenv('ARTIFACTORY_CREDS_USR') password = os.getenv('ARTIFACTORY_CREDS_PSW') -token = os.getenv('GITHUB_TOKEN') -if not username or not password or not token: - sys.exit("please set env for ARTIFACTORY_CREDS_USR, ARTIFACTORY_CREDS_PSW, and GITHUB_TOKEN") +if not username or not password: + sys.exit("please set env for ARTIFACTORY_CREDS_USR and ARTIFACTORY_CREDS_PSW") helm_stage = "release" if args.release else "dev" helm_repo = f"apim-docker-{helm_stage}-local.usw1.packages.broadcom.com" subprocess.run(['docker', 'login', helm_repo, '-u', username, '-p', password], check=True, text=True) -def download_chart(url): - local_filename = url.split("/")[-1] - headers = {'Authorization': f"Bearer {token}", 'Accept': 'application/vnd.github+json'} - - # download file - with requests.get(url, stream=True, headers=headers) as r: - r.raise_for_status() - with open(local_filename, 'wb') as f: - for chunk in r.iter_content(chunk_size=32768): - f.write(chunk) - print(f"downloaded {local_filename}") - return local_filename +def package_chart(chart_dir): + result = subprocess.run(['helm', 'package', chart_dir], check=True, text=True, capture_output=True) + print(result.stdout) + # `helm package` prints "Successfully packaged chart and saved it to: " + return result.stdout.strip().rsplit(": ", 1)[-1] def main(): - path = Path(args.index) - yaml = YAML(typ='safe') - data = yaml.load(path) - operator_url = data["entries"]["layer7-operator"][0]["urls"][0] - - print(f"working on operator: {operator_url}") - operator_chart = download_chart(operator_url) + print(f"working on operator chart: {args.chart_dir}") + operator_chart = package_chart(args.chart_dir) subprocess.run(['helm', 'push', operator_chart, f"oci://{helm_repo}"], check=True, text=True) subprocess.run(['docker', 'logout', helm_repo], check=True, text=True) From 75abe4001e94cdf532c4dc15d8d91ed431cc7785 Mon Sep 17 00:00:00 2001 From: kk640244 <219095469+kk640244@users.noreply.github.com> Date: Tue, 8 Sep 2026 20:04:25 +0530 Subject: [PATCH 04/11] Add publish gating to replace chart-releaser's idempotency (Phase 2b follow-up) chart-releaser-action (the old GH Actions flow) only ever created a new GitHub Release - and thus only ever gave the gh-pages job something new to publish - when Chart.yaml's version had actually changed since the last release. The Jenkinsfile-charts rewrite in the previous commit lost that: it would unconditionally `helm package` + `helm push` on every run, regardless of whether the chart changed at all, risking a failed or duplicate push of an already-published version. push_helm_charts.py now gates on two checks: - --check-changed TARGET_BRANCH (optional): a cheap `ct list-changed` short-circuit for PR builds, skipping entirely if the chart directory isn't in the changed list vs TARGET_BRANCH. Deliberately NOT used for the release path - `ct list-changed --target-branch main` run while already on main always reports no changes, so it would be actively wrong there. - version_exists(): before packaging, checks whether the chart's current Chart.yaml version already exists in the target Artifactory OCI repo (`helm pull ... --version `) and skips if so. This is the closer equivalent of chart-releaser's own "don't recreate an existing release" behavior, and applies to both the PR and release paths. Also wrapped login-through-logout in try/finally so a failed push no longer leaves the agent logged in (a latent issue in the original script, which called docker logout sequentially after push with no error handling). Jenkinsfile-charts: PR builds now pass --check-changed main; main builds rely solely on the version_exists() check (see above for why --check-changed doesn't apply there). Co-Authored-By: Claude Sonnet 5 --- Jenkinsfile-charts | 11 ++++++++- push_helm_charts.py | 57 +++++++++++++++++++++++++++++++++++++++------ 2 files changed, 60 insertions(+), 8 deletions(-) diff --git a/Jenkinsfile-charts b/Jenkinsfile-charts index 716a7905..01160e16 100644 --- a/Jenkinsfile-charts +++ b/Jenkinsfile-charts @@ -15,8 +15,17 @@ pipeline { // nothing further to do for a PR build). The default branch pushes // to release-local, which a separate, not-yet-built workflow later // promotes to layer7.packages.broadcom.com (Phase 2c). + // + // --check-changed is a cheap `ct list-changed` short-circuit, only + // meaningful for PR builds (comparing the PR branch against main); + // it's meaningless when already running on main itself (main vs + // main always reports no changes), so it's omitted there. Either + // way, push_helm_charts.py also checks whether the chart's current + // version already exists in the target Artifactory repo and skips + // if so - the closer equivalent to chart-releaser's own "don't + // recreate an existing release" check. if (env.CHANGE_ID) { - sh 'python3 push_helm_charts.py' + sh 'python3 push_helm_charts.py --check-changed main' } else if (env.BRANCH_NAME == 'main') { sh 'python3 push_helm_charts.py --release' } else { diff --git a/push_helm_charts.py b/push_helm_charts.py index 96d9fbef..cb5cc2e0 100644 --- a/push_helm_charts.py +++ b/push_helm_charts.py @@ -1,22 +1,29 @@ # Package the layer7-operator helm chart from this workspace and push it to -# Artifactory as an OCI artifact. +# Artifactory as an OCI artifact - but only if it's actually a new version. # # Pre-requisite: # - Artifactory credentials set in environment: ARTIFACTORY_CREDS_USR, ARTIFACTORY_CREDS_PSW +# - `ct` (chart-testing) on PATH if --check-changed is used # # command examples: # python3 push_helm_charts.py # python3 push_helm_charts.py --release +# python3 push_helm_charts.py --check-changed main # python3 push_helm_charts.py --chart-dir charts/layer7-operator import argparse import os import subprocess import sys +import tempfile -parser = argparse.ArgumentParser(description='Package and push the layer7-operator helm chart to artifactory') +parser = argparse.ArgumentParser(description='Package and push the layer7-operator helm chart to artifactory, if it is a new version') parser.add_argument('--chart-dir', default='charts/layer7-operator', help='path to the chart to package') parser.add_argument('--release', action='store_true', help='flag to push to release repo instead of dev') +parser.add_argument('--check-changed', metavar='TARGET_BRANCH', default=None, + help='skip entirely if `ct list-changed --target-branch TARGET_BRANCH` does not report ' + '--chart-dir as changed (cheap short-circuit for PR builds; meaningless when already ' + 'on the target branch itself, so omit it there)') args = parser.parse_args() username = os.getenv('ARTIFACTORY_CREDS_USR') @@ -25,7 +32,33 @@ sys.exit("please set env for ARTIFACTORY_CREDS_USR and ARTIFACTORY_CREDS_PSW") helm_stage = "release" if args.release else "dev" helm_repo = f"apim-docker-{helm_stage}-local.usw1.packages.broadcom.com" -subprocess.run(['docker', 'login', helm_repo, '-u', username, '-p', password], check=True, text=True) + +def chart_changed(chart_dir, target_branch): + result = subprocess.run(['ct', 'list-changed', '--target-branch', target_branch], + check=True, text=True, capture_output=True) + changed = [line.strip() for line in result.stdout.splitlines()] + return chart_dir.rstrip('/') in changed + +def chart_metadata(chart_dir): + name = version = None + with open(os.path.join(chart_dir, "Chart.yaml")) as f: + for line in f: + if line.startswith("name:"): + name = line.split(":", 1)[1].strip() + elif line.startswith("version:"): + version = line.split(":", 1)[1].strip() + if not name or not version: + sys.exit(f"could not read name/version from {chart_dir}/Chart.yaml") + return name, version + +def version_exists(chart_name, version): + # Mirrors chart-releaser's own "don't recreate an existing release" check, + # just against the Artifactory OCI repo instead of GitHub Releases. + with tempfile.TemporaryDirectory() as tmpdir: + result = subprocess.run( + ['helm', 'pull', f"oci://{helm_repo}/{chart_name}", '--version', version, '-d', tmpdir], + text=True, capture_output=True) + return result.returncode == 0 def package_chart(chart_dir): result = subprocess.run(['helm', 'package', chart_dir], check=True, text=True, capture_output=True) @@ -34,11 +67,21 @@ def package_chart(chart_dir): return result.stdout.strip().rsplit(": ", 1)[-1] def main(): - print(f"working on operator chart: {args.chart_dir}") - operator_chart = package_chart(args.chart_dir) - subprocess.run(['helm', 'push', operator_chart, f"oci://{helm_repo}"], check=True, text=True) + if args.check_changed and not chart_changed(args.chart_dir, args.check_changed): + print(f"no changes under {args.chart_dir} vs {args.check_changed} - skipping publish") + return - subprocess.run(['docker', 'logout', helm_repo], check=True, text=True) + chart_name, version = chart_metadata(args.chart_dir) + subprocess.run(['docker', 'login', helm_repo, '-u', username, '-p', password], check=True, text=True) + try: + if version_exists(chart_name, version): + print(f"{chart_name} {version} already published to {helm_repo} - skipping") + return + print(f"working on {chart_name} {version} from {args.chart_dir}") + operator_chart = package_chart(args.chart_dir) + subprocess.run(['helm', 'push', operator_chart, f"oci://{helm_repo}"], check=True, text=True) + finally: + subprocess.run(['docker', 'logout', helm_repo], check=True, text=True) if __name__ == "__main__": main() From 5e17a83bb97c0d40743c0f845389363db9c99dbc Mon Sep 17 00:00:00 2001 From: kk640244 <219095469+kk640244@users.noreply.github.com> Date: Tue, 8 Sep 2026 23:14:00 +0530 Subject: [PATCH 05/11] Trim migration-process references from Jenkinsfile-charts comments Comments should describe the current system on its own terms, not reference internal migration-plan phase labels or chart-releaser (the GH-Actions-era tool this pipeline replaces, which won't exist by the time anyone reads this comment again). That context belongs in commit messages, not baked into the code. Co-Authored-By: Claude Sonnet 5 --- Jenkinsfile-charts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Jenkinsfile-charts b/Jenkinsfile-charts index 01160e16..efdf4ae5 100644 --- a/Jenkinsfile-charts +++ b/Jenkinsfile-charts @@ -13,8 +13,8 @@ pipeline { // PR branches only ever push to dev-local (usw1 Artifactory blocks // promoting dev-local to layer7.packages.broadcom.com, so there's // nothing further to do for a PR build). The default branch pushes - // to release-local, which a separate, not-yet-built workflow later - // promotes to layer7.packages.broadcom.com (Phase 2c). + // to release-local; a separate promotion job pushes from there to + // layer7.packages.broadcom.com. // // --check-changed is a cheap `ct list-changed` short-circuit, only // meaningful for PR builds (comparing the PR branch against main); @@ -22,8 +22,8 @@ pipeline { // main always reports no changes), so it's omitted there. Either // way, push_helm_charts.py also checks whether the chart's current // version already exists in the target Artifactory repo and skips - // if so - the closer equivalent to chart-releaser's own "don't - // recreate an existing release" check. + // if so, to avoid pushing a duplicate of an already-published + // version. if (env.CHANGE_ID) { sh 'python3 push_helm_charts.py --check-changed main' } else if (env.BRANCH_NAME == 'main') { From aaf3b7948f031df104cfadaa8b983c5567c96bb6 Mon Sep 17 00:00:00 2001 From: kk640244 <219095469+kk640244@users.noreply.github.com> Date: Mon, 28 Sep 2026 18:17:02 +0530 Subject: [PATCH 06/11] charts dir --- push_helm_charts.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/push_helm_charts.py b/push_helm_charts.py index cb5cc2e0..8cd130d2 100644 --- a/push_helm_charts.py +++ b/push_helm_charts.py @@ -9,7 +9,7 @@ # python3 push_helm_charts.py # python3 push_helm_charts.py --release # python3 push_helm_charts.py --check-changed main -# python3 push_helm_charts.py --chart-dir charts/layer7-operator +# python3 push_helm_charts.py --chart-dir charts import argparse import os @@ -18,7 +18,7 @@ import tempfile parser = argparse.ArgumentParser(description='Package and push the layer7-operator helm chart to artifactory, if it is a new version') -parser.add_argument('--chart-dir', default='charts/layer7-operator', help='path to the chart to package') +parser.add_argument('--chart-dir', default='charts', help='path to the chart to package') parser.add_argument('--release', action='store_true', help='flag to push to release repo instead of dev') parser.add_argument('--check-changed', metavar='TARGET_BRANCH', default=None, help='skip entirely if `ct list-changed --target-branch TARGET_BRANCH` does not report ' From be1c02b150d013ca85c6192a271502a9a271c004 Mon Sep 17 00:00:00 2001 From: kk640244 <219095469+kk640244@users.noreply.github.com> Date: Tue, 29 Sep 2026 20:13:39 +0530 Subject: [PATCH 07/11] run chart on main only, remove version check, rename push_helm_charts file --- Jenkinsfile-charts | 10 ++++------ push_helm_charts.py => package_push_helm_charts.py | 6 +++--- 2 files changed, 7 insertions(+), 9 deletions(-) rename push_helm_charts.py => package_push_helm_charts.py (96%) diff --git a/Jenkinsfile-charts b/Jenkinsfile-charts index efdf4ae5..4feb56dd 100644 --- a/Jenkinsfile-charts +++ b/Jenkinsfile-charts @@ -7,7 +7,7 @@ pipeline { ARTIFACTORY_CREDS = credentials("ARTIFACTORY_USERNAME_TOKEN") } stages { - stage('Push Helm Chart') { + stage('Package and Push Helm Chart') { steps { script { // PR branches only ever push to dev-local (usw1 Artifactory blocks @@ -24,12 +24,10 @@ pipeline { // version already exists in the target Artifactory repo and skips // if so, to avoid pushing a duplicate of an already-published // version. - if (env.CHANGE_ID) { - sh 'python3 push_helm_charts.py --check-changed main' - } else if (env.BRANCH_NAME == 'main') { - sh 'python3 push_helm_charts.py --release' + if (env.BRANCH_NAME == 'main') { + sh 'python3 package_push_helm_charts.py --release' } else { - echo "not a PR and not main - skipping chart publish for branch ${env.BRANCH_NAME}" + echo "not main - skipping chart publish for branch ${env.BRANCH_NAME}" } } } diff --git a/push_helm_charts.py b/package_push_helm_charts.py similarity index 96% rename from push_helm_charts.py rename to package_push_helm_charts.py index 8cd130d2..80837f3b 100644 --- a/push_helm_charts.py +++ b/package_push_helm_charts.py @@ -74,9 +74,9 @@ def main(): chart_name, version = chart_metadata(args.chart_dir) subprocess.run(['docker', 'login', helm_repo, '-u', username, '-p', password], check=True, text=True) try: - if version_exists(chart_name, version): - print(f"{chart_name} {version} already published to {helm_repo} - skipping") - return + #if version_exists(chart_name, version): + # print(f"{chart_name} {version} already published to {helm_repo} - skipping") + # return print(f"working on {chart_name} {version} from {args.chart_dir}") operator_chart = package_chart(args.chart_dir) subprocess.run(['helm', 'push', operator_chart, f"oci://{helm_repo}"], check=True, text=True) From cc57feb79d7c28b6d5e4ffe3dc3fa36fdd6c7d23 Mon Sep 17 00:00:00 2001 From: kk640244 <219095469+kk640244@users.noreply.github.com> Date: Tue, 29 Sep 2026 20:28:21 +0530 Subject: [PATCH 08/11] comment change --- Jenkinsfile-charts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile-charts b/Jenkinsfile-charts index 4feb56dd..7bab957a 100644 --- a/Jenkinsfile-charts +++ b/Jenkinsfile-charts @@ -14,7 +14,7 @@ pipeline { // promoting dev-local to layer7.packages.broadcom.com, so there's // nothing further to do for a PR build). The default branch pushes // to release-local; a separate promotion job pushes from there to - // layer7.packages.broadcom.com. + // packages.broadcom.com. // // --check-changed is a cheap `ct list-changed` short-circuit, only // meaningful for PR builds (comparing the PR branch against main); From 134b1dda07a9aa2b0541b2d67825894dc3e28857 Mon Sep 17 00:00:00 2001 From: kk640244 <219095469+kk640244@users.noreply.github.com> Date: Wed, 30 Sep 2026 10:38:25 +0530 Subject: [PATCH 09/11] comment removed --- Jenkinsfile-charts | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/Jenkinsfile-charts b/Jenkinsfile-charts index 7bab957a..201e9b59 100644 --- a/Jenkinsfile-charts +++ b/Jenkinsfile-charts @@ -10,20 +10,6 @@ pipeline { stage('Package and Push Helm Chart') { steps { script { - // PR branches only ever push to dev-local (usw1 Artifactory blocks - // promoting dev-local to layer7.packages.broadcom.com, so there's - // nothing further to do for a PR build). The default branch pushes - // to release-local; a separate promotion job pushes from there to - // packages.broadcom.com. - // - // --check-changed is a cheap `ct list-changed` short-circuit, only - // meaningful for PR builds (comparing the PR branch against main); - // it's meaningless when already running on main itself (main vs - // main always reports no changes), so it's omitted there. Either - // way, push_helm_charts.py also checks whether the chart's current - // version already exists in the target Artifactory repo and skips - // if so, to avoid pushing a duplicate of an already-published - // version. if (env.BRANCH_NAME == 'main') { sh 'python3 package_push_helm_charts.py --release' } else { From d232f42b3a206889cae956c850a7e7dbcb146826 Mon Sep 17 00:00:00 2001 From: kk640244 <219095469+kk640244@users.noreply.github.com> Date: Wed, 30 Sep 2026 13:39:54 +0530 Subject: [PATCH 10/11] set release_version to tag if tag --- Jenkinsfile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Jenkinsfile b/Jenkinsfile index 4c939e18..dc4c76c6 100755 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -30,6 +30,10 @@ pipeline { usernamePassword(credentialsId: 'ARTIFACTORY_USERNAME_TOKEN', usernameVariable: 'ARTIFACTORY_DEV_LOCAL_USERNAME', passwordVariable: 'ARTIFACTORY_DEV_LOCAL_APIKEY') ]){ sh ''' + if [[ -n "${TAG_NAME}" ]]; then + export RELEASE_VERSION="${TAG_NAME#v}" + fi + if [[ -z "${RELEASE_VERSION}" ]]; then if [[ "${BRANCH_NAME}" = "develop" ]]; then export IMAGE_TAG="latest" From 6441a4207042584083500a7d490073fc00faee37 Mon Sep 17 00:00:00 2001 From: kk640244 <219095469+kk640244@users.noreply.github.com> Date: Tue, 6 Oct 2026 23:18:19 +0530 Subject: [PATCH 11/11] git branch and arti fix --- Jenkinsfile-charts | 4 ++-- package_push_helm_charts.py | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Jenkinsfile-charts b/Jenkinsfile-charts index 201e9b59..e6d59351 100644 --- a/Jenkinsfile-charts +++ b/Jenkinsfile-charts @@ -10,10 +10,10 @@ pipeline { stage('Package and Push Helm Chart') { steps { script { - if (env.BRANCH_NAME == 'main') { + if (env.GIT_BRANCH == 'main' || env.GIT_BRANCH == 'origin/main') { sh 'python3 package_push_helm_charts.py --release' } else { - echo "not main - skipping chart publish for branch ${env.BRANCH_NAME}" + echo "not main - skipping chart publish for branch ${env.GIT_BRANCH}" } } } diff --git a/package_push_helm_charts.py b/package_push_helm_charts.py index 80837f3b..686a5bdd 100644 --- a/package_push_helm_charts.py +++ b/package_push_helm_charts.py @@ -3,6 +3,7 @@ # # Pre-requisite: # - Artifactory credentials set in environment: ARTIFACTORY_CREDS_USR, ARTIFACTORY_CREDS_PSW +# - Artifactory hosts set in environment: DOCKER_SNAPSHOT_REG (dev), DOCKER_RELEASE_REG (release) - # - `ct` (chart-testing) on PATH if --check-changed is used # # command examples: @@ -30,8 +31,9 @@ password = os.getenv('ARTIFACTORY_CREDS_PSW') if not username or not password: sys.exit("please set env for ARTIFACTORY_CREDS_USR and ARTIFACTORY_CREDS_PSW") -helm_stage = "release" if args.release else "dev" -helm_repo = f"apim-docker-{helm_stage}-local.usw1.packages.broadcom.com" +helm_repo = os.getenv('DOCKER_RELEASE_REG') if args.release else os.getenv('DOCKER_SNAPSHOT_REG') +if not helm_repo: + sys.exit("please set env for DOCKER_RELEASE_REG and DOCKER_SNAPSHOT_REG") def chart_changed(chart_dir, target_branch): result = subprocess.run(['ct', 'list-changed', '--target-branch', target_branch],