From 6207ce11f5be9d925f64622e79130dcd20d93342 Mon Sep 17 00:00:00 2001 From: Rajan Agaskar Date: Thu, 10 Sep 2026 12:51:15 -0700 Subject: [PATCH] Add MANUALLY_BYPASS_SUBMISSION flag to azure upload/publish task The Azure Partner Center was observed to return spurious validation errors around offer logos when submitting via API. We bypassed this by submitting "manually" via the Partner Center UX, but we would still like the `azure-image-upload-and-start-publishing` job to run successfully to allow the remaining pipeline jobs to complete as expected. This commit adds a manual bypass with a number of safety checks to minimize the possibility of issues if the bypass configuration is left in place. To guard against accidentally leaving the bypass on, the flag value must be set to today's date in Pacific time (YYYY-MM-DD). A stale date causes the job to fail with instructions. Additionally the job verifies: 1. The expected image version and blob URL are already present in the offer JSON (confirming the manual submission actually happened). 2. The offer's publisher-signoff step is not "complete" (which would indicate the offer already published and a re-trigger is a mistake). If all checks pass, the job logs a loud WARNING banner and exits 0 so the pipeline continues to wait-for-azure-publisher-signoff as normal. Co-Authored-By: Claude Sonnet 4.6 (1M context) ai-assisted=yes [TNZ-88995] --- ci/pipelines/stemcells-windows.yml | 1 + .../run | 77 +++++++++++++++++++ .../task.yml | 1 + 3 files changed, 79 insertions(+) diff --git a/ci/pipelines/stemcells-windows.yml b/ci/pipelines/stemcells-windows.yml index eee70ee0d..c4479b2bb 100644 --- a/ci/pipelines/stemcells-windows.yml +++ b/ci/pipelines/stemcells-windows.yml @@ -2440,6 +2440,7 @@ jobs: PARTNER_PORTAL_CLIENT_ID: ((azure_partner_portal.client_id)) PARTNER_PORTAL_CLIENT_SECRET: ((azure_partner_portal.client_secret)) OFFER_NOTIFICATION_EMAIL: boshwindows@groups.vmware.com + MANUALLY_BYPASS_SUBMISSION: "" # TODO: replace `upload-image-and-start-publishing` with the two tasks below # - task: azure-image-upload # file: bosh-windows-stemcell-builder-ci/ci/tasks/azure-image-upload/task.yml diff --git a/ci/tasks/azure-image-upload-and-start-publishing/run b/ci/tasks/azure-image-upload-and-start-publishing/run index df4d43a0e..1326e0e33 100755 --- a/ci/tasks/azure-image-upload-and-start-publishing/run +++ b/ci/tasks/azure-image-upload-and-start-publishing/run @@ -131,6 +131,83 @@ publish_offer() { -H "Authorization: Bearer $token" } +if [[ "${MANUALLY_BYPASS_SUBMISSION:-}" != "" ]]; then + pacific_today=$(TZ="America/Los_Angeles" date +%Y-%m-%d) + + if ! echo "${MANUALLY_BYPASS_SUBMISSION}" | grep -qE '^[0-9]{4}-[0-9]{2}-[0-9]{2}$'; then + echo "ERROR: MANUALLY_BYPASS_SUBMISSION is set to '${MANUALLY_BYPASS_SUBMISSION}' which is not a valid YYYY-MM-DD date." + echo "To bypass submission today, set MANUALLY_BYPASS_SUBMISSION to: ${pacific_today}" + exit 1 + fi + + if [[ "${MANUALLY_BYPASS_SUBMISSION}" != "${pacific_today}" ]]; then + echo "ERROR: MANUALLY_BYPASS_SUBMISSION date '${MANUALLY_BYPASS_SUBMISSION}' does not match today's Pacific date '${pacific_today}'." + echo "To bypass submission today, set MANUALLY_BYPASS_SUBMISSION to: ${pacific_today}" + exit 1 + fi + + echo "Date check passed: MANUALLY_BYPASS_SUBMISSION matches today's Pacific date (${pacific_today})." + + echo "Authenticating with Microsoft..." + token=$(create_microsoft_token) + echo OK + + offer_id_endpoint="https://cloudpartner.azure.com/api/publishers/$AZURE_PUBLISHER/offers/$AZURE_OFFER?api-version=2017-10-31" + + echo "Retrieving current offer to verify image was already added..." + original_offer_json="$PWD/original_offer.json" + create_original_offer_json > "$original_offer_json" + + image_version=$(format_version "$main_version") + blob_url=$(retrieve_blob_url) + + existing_vhd_url=$(jq -r " + .definition.plans[] | + select(.planId == \"$AZURE_SKU\") | + .[\"microsoft-azure-virtualmachines.vmImages\"][\"$image_version\"].osVhdUrl + " "$original_offer_json") + + if [[ -z "${existing_vhd_url}" || "${existing_vhd_url}" == "null" ]]; then + echo "ERROR: Image version '${image_version}' not found in offer for plan '${AZURE_SKU}'." + echo "The offer does not contain the expected image. Verify that manual submission was completed." + exit 1 + fi + + if [[ "${existing_vhd_url}" != "${blob_url}"* ]]; then + echo "ERROR: The existing osVhdUrl '${existing_vhd_url}' does not start with expected blob URL '${blob_url}'." + echo "The offer may not have been updated with the correct image." + exit 1 + fi + + echo "Image check passed: image version '${image_version}' with expected blob URL found in offer." + + echo "Checking offer status..." + offer_status_endpoint="https://cloudpartner.azure.com/api/publishers/$AZURE_PUBLISHER/offers/$AZURE_OFFER/status?api-version=2017-10-31" + offer_status_json="$PWD/offer_status.json" + curl --fail -X GET "$offer_status_endpoint" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $token" > "$offer_status_json" + + signoff_step_status=$(jq -er ".steps[] | select(.id == \"publisher-signoff\") | .status" "$offer_status_json") + + if [[ "${signoff_step_status}" == "complete" ]]; then + echo "ERROR: Offer publisher-signoff status is 'complete'. The offer has already been published." + echo "Do not use MANUALLY_BYPASS_SUBMISSION when the offer is already complete." + exit 1 + fi + + echo + echo "========================================================================" + echo "WARNING: MANUALLY BYPASSING AZURE MARKETPLACE SUBMISSION" + echo "The submission was performed manually outside of this pipeline job." + echo "All safety checks passed. Proceeding to wait-for-azure-publisher-signoff." + echo " Offer status (publisher-signoff step): ${signoff_step_status}" + echo " Bypass authorized for date: ${MANUALLY_BYPASS_SUBMISSION}" + echo "========================================================================" + echo + exit 0 +fi + echo -n "Authenticating with Microsoft..." echo token=$(create_microsoft_token) diff --git a/ci/tasks/azure-image-upload-and-start-publishing/task.yml b/ci/tasks/azure-image-upload-and-start-publishing/task.yml index 043b891ff..1aaa6d89e 100644 --- a/ci/tasks/azure-image-upload-and-start-publishing/task.yml +++ b/ci/tasks/azure-image-upload-and-start-publishing/task.yml @@ -23,4 +23,5 @@ params: PARTNER_PORTAL_CLIENT_ID: PARTNER_PORTAL_CLIENT_SECRET: OFFER_NOTIFICATION_EMAIL: + MANUALLY_BYPASS_SUBMISSION: