From 26c6fe946396a8ad408455d2e9a941977c35c387 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 7 Apr 2026 13:55:27 -0400 Subject: [PATCH] fix: add pull_request_url and branch_name to CodeBuild success response returning repository_url/repository_name, causing CFN to fail with: 'Vendor response doesn't contain pull_request_url attribute' After CodeBuild SUCCEEDED, query GitHub API /pulls?state=open on the created repo to get the real PR URL and branch name. --- template_automation/app.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/template_automation/app.py b/template_automation/app.py index 0cffae3..d21d366 100644 --- a/template_automation/app.py +++ b/template_automation/app.py @@ -736,11 +736,40 @@ def lambda_handler(event: dict, context) -> dict: repo_base = github_api.rstrip("/").removesuffix("/api/v3") github_org = os.environ.get("GITHUB_ORG_NAME", "SCT-Engineering") repo_url = f"{repo_base}/{github_org}/{cfn_input.project_name}" + + # Fetch the open PR so we can return pull_request_url and branch_name + # (both are required by the CloudFormation template Outputs section). + pull_request_url = "N/A" + branch_name = "repo-init" + try: + import urllib.request as _urllib + api_base = github_api.rstrip("/") + prs_url = f"{api_base}/repos/{github_org}/{cfn_input.project_name}/pulls?state=open" + req = _urllib.Request(prs_url, headers={"Authorization": f"token {github_token}"}) + import ssl as _ssl + ctx = _ssl.create_default_context() + ctx.check_hostname = False + ctx.verify_mode = _ssl.CERT_NONE + with _urllib.urlopen(req, context=ctx, timeout=10) as resp: + prs = json.loads(resp.read()) + if prs: + pull_request_url = prs[0].get("html_url", "N/A") + branch_name = prs[0].get("head", {}).get("ref", "repo-init") + logger.info(f"[{request_id}] Found PR: {pull_request_url} (branch: {branch_name})") + else: + logger.warning(f"[{request_id}] No open PRs found on {cfn_input.project_name}") + except Exception as pr_err: + logger.warning(f"[{request_id}] Could not fetch PR URL: {pr_err}") + response_data = { "RepositoryUrl": repo_url, "repository_url": repo_url, "RepositoryName": cfn_input.project_name, "repository_name": cfn_input.project_name, + "PullRequestUrl": pull_request_url, + "pull_request_url": pull_request_url, + "BranchName": branch_name, + "branch_name": branch_name, "CodeBuildBuildId": build_id, } physical_resource_id = f"{cfn_input.project_name}-repository"