From cf2311083501e1e55095ca0fbfafca4cdf3e2de0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 28 Feb 2026 10:30:24 +0000 Subject: [PATCH 1/3] Initial plan From 69c510de74bdfafcad8f76dc0a6c747e8684e5ed Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 28 Feb 2026 10:35:47 +0000 Subject: [PATCH 2/3] Add GitHub workflows to trigger Azure DevOps CI and CD pipelines Co-authored-by: haavamoa <2527084+haavamoa@users.noreply.github.com> --- .github/workflows/trigger-azure-cd.yml | 78 ++++++++++++++++++++++++++ .github/workflows/trigger-azure-ci.yml | 50 +++++++++++++++++ CHANGELOG.md | 3 + 3 files changed, 131 insertions(+) create mode 100644 .github/workflows/trigger-azure-cd.yml create mode 100644 .github/workflows/trigger-azure-ci.yml diff --git a/.github/workflows/trigger-azure-cd.yml b/.github/workflows/trigger-azure-cd.yml new file mode 100644 index 00000000..23c70a22 --- /dev/null +++ b/.github/workflows/trigger-azure-cd.yml @@ -0,0 +1,78 @@ +name: Trigger Azure DevOps CD + +# This workflow triggers an Azure DevOps CD pipeline build. +# +# Access is restricted via the "protected" GitHub Environment, which must be +# configured in the repository Settings → Environments with required reviewers +# and/or deployment branch rules before the job is allowed to run. +# +# Required repository secrets (Settings → Secrets and variables → Actions): +# AZURE_DEVOPS_TOKEN – Azure DevOps Personal Access Token with +# "Build: Read & execute" scope +# +# Required repository variables (Settings → Secrets and variables → Actions): +# AZURE_CD_PIPELINE_ID – Azure DevOps pipeline definition ID to trigger + +on: + workflow_dispatch: + inputs: + task: + description: 'Build task to run' + required: true + type: choice + options: + - ci + - publishApp + - publish + - dryRun + branch: + description: 'Branch to build (defaults to main)' + required: false + default: 'main' + is_dry_run: + description: 'Dry run – validate without publishing' + type: boolean + default: false + +jobs: + trigger-cd: + name: Trigger CD pipeline + runs-on: ubuntu-latest + permissions: {} + # The "protected" environment enforces required-reviewer approval before + # this job proceeds. Configure reviewers and branch policies in: + # Settings → Environments → protected + environment: protected + steps: + - name: Queue Azure DevOps CD build + env: + AZURE_DEVOPS_TOKEN: ${{ secrets.AZURE_DEVOPS_TOKEN }} + # Pass user-controlled values via env vars to prevent script injection + INPUT_BRANCH: ${{ inputs.branch }} + INPUT_TASK: ${{ inputs.task }} + run: | + BRANCH_REF="refs/heads/${INPUT_BRANCH}" + TASK="${INPUT_TASK}" + IS_DRY_RUN="${{ inputs.is_dry_run }}" + + HTTP_STATUS=$(curl -s -o /tmp/response.json -w "%{http_code}" \ + -X POST \ + -H "Authorization: Basic $(echo -n ":${AZURE_DEVOPS_TOKEN}" | base64 -w 0)" \ + -H "Content-Type: application/json" \ + -d "{ + \"definition\": {\"id\": ${{ vars.AZURE_CD_PIPELINE_ID }} }, + \"sourceBranch\": \"${BRANCH_REF}\", + \"parameters\": \"{\\\"task\\\":\\\"${TASK}\\\",\\\"IsDryRun\\\":\\\"${IS_DRY_RUN}\\\",\\\"GitHubRunId\\\":\\\"${{ github.run_id }}\\\",\\\"GitHubActor\\\":\\\"${{ github.actor }}\\\"}\"\ + }" \ + "https://dev.azure.com/dips/DIPS/_apis/build/builds?api-version=7.0") + + echo "HTTP status: $HTTP_STATUS" + cat /tmp/response.json + + if [ "$HTTP_STATUS" != "200" ] && [ "$HTTP_STATUS" != "201" ]; then + echo "❌ Failed to queue build (HTTP $HTTP_STATUS)" + exit 1 + fi + + BUILD_URL=$(python3 -c "import sys, json; d=json.load(open('/tmp/response.json')); print(d.get('_links',{}).get('web',{}).get('href','N/A'))") + echo "✅ CD build queued: $BUILD_URL" diff --git a/.github/workflows/trigger-azure-ci.yml b/.github/workflows/trigger-azure-ci.yml new file mode 100644 index 00000000..3354e1c0 --- /dev/null +++ b/.github/workflows/trigger-azure-ci.yml @@ -0,0 +1,50 @@ +name: Trigger Azure DevOps CI + +on: + push: + branches: [main] + pull_request: + branches: [main] + types: [opened, synchronize, reopened] + +jobs: + trigger-ci: + name: Trigger CI pipeline + runs-on: ubuntu-latest + permissions: {} + steps: + - name: Queue Azure DevOps CI build + env: + AZURE_DEVOPS_TOKEN: ${{ secrets.AZURE_DEVOPS_TOKEN }} + # Pass user-controlled values via env vars to prevent script injection + GH_EVENT_NAME: ${{ github.event_name }} + GH_HEAD_REF: ${{ github.head_ref }} + GH_REF: ${{ github.ref }} + run: | + if [ "${GH_EVENT_NAME}" = "pull_request" ]; then + BRANCH_REF="refs/heads/${GH_HEAD_REF}" + else + BRANCH_REF="${GH_REF}" + fi + + HTTP_STATUS=$(curl -s -o /tmp/response.json -w "%{http_code}" \ + -X POST \ + -H "Authorization: Basic $(echo -n ":${AZURE_DEVOPS_TOKEN}" | base64 -w 0)" \ + -H "Content-Type: application/json" \ + -d "{ + \"definition\": {\"id\": ${{ vars.AZURE_CI_PIPELINE_ID }} }, + \"sourceBranch\": \"${BRANCH_REF}\", + \"parameters\": \"{\\\"GitHubRunId\\\":\\\"${{ github.run_id }}\\\",\\\"GitHubRef\\\":\\\"${{ github.ref }}\\\",\\\"GitHubSHA\\\":\\\"${{ github.sha }}\\\"}\" + }" \ + "https://dev.azure.com/dips/DIPS/_apis/build/builds?api-version=7.0") + + echo "HTTP status: $HTTP_STATUS" + cat /tmp/response.json + + if [ "$HTTP_STATUS" != "200" ] && [ "$HTTP_STATUS" != "201" ]; then + echo "❌ Failed to queue build (HTTP $HTTP_STATUS)" + exit 1 + fi + + BUILD_URL=$(python3 -c "import sys, json; d=json.load(open('/tmp/response.json')); print(d.get('_links',{}).get('web',{}).get('href','N/A'))") + echo "✅ CI build queued: $BUILD_URL" diff --git a/CHANGELOG.md b/CHANGELOG.md index 566fc835..4f1d3768 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## [55.2.3] +- [CI/CD] Added GitHub workflows to trigger Azure DevOps CI and CD pipelines, with access restriction via GitHub Environments. + ## [55.2.2] - [iOS26][Tip] Added more padding. From 3a641132297d9fe4202e9f5d06d989f2c475ec92 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 28 Feb 2026 10:38:05 +0000 Subject: [PATCH 3/3] Simplify trigger-azure-cd workflow to a plain branch-based build trigger Co-authored-by: haavamoa <2527084+haavamoa@users.noreply.github.com> --- .github/workflows/trigger-azure-cd.yml | 41 ++++++++------------------ 1 file changed, 12 insertions(+), 29 deletions(-) diff --git a/.github/workflows/trigger-azure-cd.yml b/.github/workflows/trigger-azure-cd.yml index 23c70a22..c51ae242 100644 --- a/.github/workflows/trigger-azure-cd.yml +++ b/.github/workflows/trigger-azure-cd.yml @@ -1,6 +1,6 @@ -name: Trigger Azure DevOps CD +name: Trigger Azure DevOps Build -# This workflow triggers an Azure DevOps CD pipeline build. +# Manually start a build in Azure DevOps from any branch. # # Access is restricted via the "protected" GitHub Environment, which must be # configured in the repository Settings → Environments with required reviewers @@ -11,32 +11,19 @@ name: Trigger Azure DevOps CD # "Build: Read & execute" scope # # Required repository variables (Settings → Secrets and variables → Actions): -# AZURE_CD_PIPELINE_ID – Azure DevOps pipeline definition ID to trigger +# AZURE_PIPELINE_ID – Azure DevOps pipeline definition ID to trigger on: workflow_dispatch: inputs: - task: - description: 'Build task to run' - required: true - type: choice - options: - - ci - - publishApp - - publish - - dryRun branch: - description: 'Branch to build (defaults to main)' - required: false + description: 'Branch to build' + required: true default: 'main' - is_dry_run: - description: 'Dry run – validate without publishing' - type: boolean - default: false jobs: - trigger-cd: - name: Trigger CD pipeline + trigger-build: + name: Trigger Azure DevOps build runs-on: ubuntu-latest permissions: {} # The "protected" environment enforces required-reviewer approval before @@ -44,25 +31,21 @@ jobs: # Settings → Environments → protected environment: protected steps: - - name: Queue Azure DevOps CD build + - name: Queue Azure DevOps build env: AZURE_DEVOPS_TOKEN: ${{ secrets.AZURE_DEVOPS_TOKEN }} - # Pass user-controlled values via env vars to prevent script injection + # Pass user-controlled value via env var to prevent script injection INPUT_BRANCH: ${{ inputs.branch }} - INPUT_TASK: ${{ inputs.task }} run: | BRANCH_REF="refs/heads/${INPUT_BRANCH}" - TASK="${INPUT_TASK}" - IS_DRY_RUN="${{ inputs.is_dry_run }}" HTTP_STATUS=$(curl -s -o /tmp/response.json -w "%{http_code}" \ -X POST \ -H "Authorization: Basic $(echo -n ":${AZURE_DEVOPS_TOKEN}" | base64 -w 0)" \ -H "Content-Type: application/json" \ -d "{ - \"definition\": {\"id\": ${{ vars.AZURE_CD_PIPELINE_ID }} }, - \"sourceBranch\": \"${BRANCH_REF}\", - \"parameters\": \"{\\\"task\\\":\\\"${TASK}\\\",\\\"IsDryRun\\\":\\\"${IS_DRY_RUN}\\\",\\\"GitHubRunId\\\":\\\"${{ github.run_id }}\\\",\\\"GitHubActor\\\":\\\"${{ github.actor }}\\\"}\"\ + \"definition\": {\"id\": ${{ vars.AZURE_PIPELINE_ID }} }, + \"sourceBranch\": \"${BRANCH_REF}\" }" \ "https://dev.azure.com/dips/DIPS/_apis/build/builds?api-version=7.0") @@ -75,4 +58,4 @@ jobs: fi BUILD_URL=$(python3 -c "import sys, json; d=json.load(open('/tmp/response.json')); print(d.get('_links',{}).get('web',{}).get('href','N/A'))") - echo "✅ CD build queued: $BUILD_URL" + echo "✅ Build queued: $BUILD_URL"