diff --git a/.github/workflows/deploy-netlify-prebuilt.yml b/.github/workflows/deploy-netlify-prebuilt.yml index d1f0515c10..b8adfe136c 100644 --- a/.github/workflows/deploy-netlify-prebuilt.yml +++ b/.github/workflows/deploy-netlify-prebuilt.yml @@ -697,8 +697,7 @@ jobs: if ( !relay?.is_secret || !relay.scopes?.includes("runtime") || - typeof value?.value !== "string" || - value.value.length === 0 + !value ) { throw new Error( "AGENT_NATIVE_GOOGLE_OAUTH_RELAY_SECRET is not provisioned as a runtime secret for " + @@ -706,8 +705,27 @@ jobs: ".", ); } - console.log("Verified Google OAuth relay secret for " + context + "."); ' "$relay_context" + if ! netlify env:get AGENT_NATIVE_GOOGLE_OAUTH_RELAY_SECRET \ + --site "$NETLIFY_SITE_ID" \ + --context "$relay_context" \ + --scope runtime \ + --auth "$NETLIFY_AUTH_TOKEN" \ + --json 2>/dev/null | + node -e ' + const fs = require("node:fs"); + const resolved = JSON.parse(fs.readFileSync(0, "utf8")); + const value = resolved.AGENT_NATIVE_GOOGLE_OAUTH_RELAY_SECRET; + if (typeof value !== "string" || value.length === 0) { + throw new Error( + "AGENT_NATIVE_GOOGLE_OAUTH_RELAY_SECRET does not resolve.", + ); + } + '; then + echo "::error::AGENT_NATIVE_GOOGLE_OAUTH_RELAY_SECRET does not resolve for $relay_context." + exit 1 + fi + echo "Verified Google OAuth relay secret for $relay_context." - name: Package the prebuilt artifact if: inputs.artifact_upload && inputs.migration_only != true diff --git a/scripts/guard-netlify-prebuilt-workflow.test.ts b/scripts/guard-netlify-prebuilt-workflow.test.ts index d26823353a..919a061d81 100644 --- a/scripts/guard-netlify-prebuilt-workflow.test.ts +++ b/scripts/guard-netlify-prebuilt-workflow.test.ts @@ -120,6 +120,30 @@ describe("Google callback deploy verification guard", () => { /if \[\[ \"\$TARGET\" == \"beta\" && \"\$DEPLOY_MODE\" == \"production\" \]\]/, ); assert.match(step, /relay_context=production/); + assert.match(step, /!value/); + assert.match( + step, + /netlify env:get AGENT_NATIVE_GOOGLE_OAUTH_RELAY_SECRET[\s\S]*--scope runtime[\s\S]*--json 2>\/dev\/null \|[\s\S]*node -e/, + ); + const resolverScript = step.match( + /--json 2>\/dev\/null \|\n\s*node -e '\n([\s\S]*?)\n\s*'/, + )?.[1]; + assert.ok(resolverScript); + const runResolver = (json: string) => + execFileSync(process.execPath, ["-e", resolverScript], { + encoding: "utf8", + input: json, + stdio: ["pipe", "pipe", "pipe"], + }); + assert.throws( + () => runResolver("{}"), + /AGENT_NATIVE_GOOGLE_OAUTH_RELAY_SECRET does not resolve/, + ); + assert.doesNotThrow(() => + runResolver( + '{"AGENT_NATIVE_GOOGLE_OAUTH_RELAY_SECRET":"test-relay-secret"}', + ), + ); assert.match( step, /node -e[\s\S]*process\.argv\[1\][\s\S]*' \"\$relay_context\"/,