diff --git a/.pipelines/.vsts-vhd-automation.yaml b/.pipelines/.vsts-vhd-automation.yaml index 21504817e87..e2940121b38 100644 --- a/.pipelines/.vsts-vhd-automation.yaml +++ b/.pipelines/.vsts-vhd-automation.yaml @@ -36,6 +36,7 @@ stages: - template: ./templates/.configure-azdevops-template.yaml parameters: ADO_PAT: $(PAT-aksdevassistant) + - template: ./templates/.generate-github-token.yaml - template: ./templates/.set-image-version-template.yaml parameters: VHD_BUILD_ID: ${{ parameters.VHD_BUILD_ID }} @@ -44,7 +45,7 @@ stages: echo "PR for Image Bumping, Official Branch Cutting" /bin/bash vhdbuilder/scripts/automate_version_bump.sh env: - GITHUB_PAT: $(PAT-aks-node-assistant) + GITHUB_TOKEN: $(GITHUB_TOKEN) IMAGE_VERSION: $(IMAGE_VERSION) VHD_BUILD_ID: ${{ parameters.VHD_BUILD_ID }} PR_TARGET_BRANCH: ${{ parameters.PRTargetBranch }} @@ -59,6 +60,7 @@ stages: - template: ./templates/.configure-azdevops-template.yaml parameters: ADO_PAT: $(PAT-aksdevassistant) + - template: ./templates/.generate-github-token.yaml - template: ./templates/.set-image-version-template.yaml parameters: VHD_BUILD_ID: ${{ parameters.VHD_BUILD_ID }} @@ -67,7 +69,7 @@ stages: echo "PR for Release Notes" /bin/bash vhdbuilder/scripts/automate_release_notes.sh env: - GITHUB_PAT: $(PAT-aks-node-assistant) + GITHUB_TOKEN: $(GITHUB_TOKEN) IMAGE_VERSION: $(IMAGE_VERSION) VHD_BUILD_ID: ${{ parameters.VHD_BUILD_ID }} SKIP_LATEST: $(SKIP_LATEST_RELEASE_NOTES_UPDATE) diff --git a/.pipelines/.vsts-vhd-windows-automation.yaml b/.pipelines/.vsts-vhd-windows-automation.yaml index 3b46b719698..6317ffc52ae 100644 --- a/.pipelines/.vsts-vhd-windows-automation.yaml +++ b/.pipelines/.vsts-vhd-windows-automation.yaml @@ -5,12 +5,9 @@ pool: parameters: - name: ImageBump - displayName: Image Bump + Branch Cutting + displayName: Image Bump type: boolean default: false -- name: GithubUserName - displayName: The user name of the owner to push changes - type: string - name: ReleaseNotes displayName: Release Notes type: boolean @@ -20,37 +17,32 @@ variables: - group: "AKS Dev Assistant (KV)" steps: +- template: ./templates/.configure-azdevops-template.yaml + parameters: + ADO_PAT: $(PAT-aksdevassistant) +- template: ./templates/.generate-github-token.yaml - bash: | - az extension add -n azure-devops - echo $MAPPED_ADO_PAT | az devops login --organization=https://dev.azure.com/msazure - az devops configure --defaults organization=https://dev.azure.com/msazure project=CloudNativeCompute + echo "Bumping windows VHD base image version" + /bin/bash vhdbuilder/scripts/windows/automate_version_bump.sh "$GITHUB_TOKEN" "$CHERRY_PICK_COMMIT_ID" env: - MAPPED_ADO_PAT: $(PAT-aksdevassistant) - displayName: 'az devops login' -- bash: | - echo "Bumping windows VHD base image version" - /bin/bash vhdbuilder/scripts/windows/automate_version_bump.sh $MAPPED_GITHUB_PAT '${{ parameters.GithubUserName }}' "$CHERRY_PICK_COMMIT_ID" - env: - MAPPED_GITHUB_PAT: $(GITHUB_PAT) + GITHUB_TOKEN: $(GITHUB_TOKEN) + CHERRY_PICK_COMMIT_ID: $(CHERRY_PICK_COMMIT_ID) displayName: 'Image Version Bumping' condition: eq('${{ parameters.ImageBump }}', true) - bash: | - echo "PR for Release Notes" - az extension add -n azure-devops - echo $MAPPED_ADO_PAT | az devops login --organization=https://dev.azure.com/msazure - az devops configure --defaults organization=https://dev.azure.com/msazure project=CloudNativeCompute - cd vhdbuilder/release-notes/autonotes - VER=$(go version) - echo "Go version is $VER" - go install . - cd ../../.. - echo "go run autonotes to shuffle release note files from Azure Pipelines into the AgentBaker repo structure" - go run vhdbuilder/release-notes/autonotes/main.go --build $BUILD_ID --include 2019-containerd,2022-containerd,2022-containerd-gen2,23H2,23H2-gen2 - echo "run bash to create pull request for the shuffled release note files" - /bin/bash vhdbuilder/scripts/windows/automate_release_notes.sh $BUILD_ID $MAPPED_GITHUB_PAT '${{ parameters.GithubUserName }}' + echo "PR for Release Notes" + cd vhdbuilder/release-notes/autonotes + VER=$(go version) + echo "Go version is $VER" + go install . + cd ../../.. + echo "go run autonotes to shuffle release note files from Azure Pipelines into the AgentBaker repo structure" + go run vhdbuilder/release-notes/autonotes/main.go --build $BUILD_ID --include 2019-containerd,2022-containerd,2022-containerd-gen2,23H2,23H2-gen2 + echo "run bash to create pull request for the shuffled release note files" + /bin/bash vhdbuilder/scripts/windows/automate_release_notes.sh "$GITHUB_TOKEN" "$BUILD_ID" env: - MAPPED_GITHUB_PAT: $(GITHUB_PAT) - MAPPED_ADO_PAT: $(PAT-aksdevassistant) + GITHUB_TOKEN: $(GITHUB_TOKEN) + BUILD_ID: $(BUILD_ID) displayName: 'Release Notes' condition: eq('${{ parameters.ReleaseNotes }}', true) \ No newline at end of file diff --git a/.pipelines/templates/.builder-release-template-windows.yaml b/.pipelines/templates/.builder-release-template-windows.yaml index 779ca8f4170..5adae8eac7d 100644 --- a/.pipelines/templates/.builder-release-template-windows.yaml +++ b/.pipelines/templates/.builder-release-template-windows.yaml @@ -246,6 +246,7 @@ steps: -e OS_NAME="Windows" \ -e SKU_NAME=${SKU_NAME} \ -e OFFER_NAME="Windows" \ + -e MODE=$(MODE) \ -e IMAGE_VERSION=${AKS_WINDOWS_IMAGE_VERSION} \ -e HYPERV_GENERATION=${HYPERV_GENERATION} \ -e OS_TYPE="Windows" \ diff --git a/.pipelines/templates/.generate-github-token.yaml b/.pipelines/templates/.generate-github-token.yaml new file mode 100644 index 00000000000..d0cde88328a --- /dev/null +++ b/.pipelines/templates/.generate-github-token.yaml @@ -0,0 +1,64 @@ +steps: +- bash: | + set -euo pipefail + + if [ -z "$PRIVATE_KEY" ]; then + echo "PRIVATE_KEY must be supplied to generate installation token for aks-node-sig-release-assistant" + exit 1 + fi + if [ -z "$CLIENT_ID" ]; then + echo "CLIENT_ID must be supplied to generate installation token for aks-node-sig-release-assistant" + exit 1 + fi + + now=$(date +%s) + iat=$((${now} - 60)) # issues 60 seconds in the past + exp=$((${now} + 600)) # expires 10 minutes in the future + + b64enc() { openssl base64 | tr -d '=' | tr '/+' '_-' | tr -d '\n'; } + + header_json='{ + "typ":"JWT", + "alg":"RS256" + }' + # encode the JWT header + header=$(echo -n "${header_json}" | b64enc) + + payload_json="{ + \"iat\":${iat}, + \"exp\":${exp}, + \"iss\":\"${CLIENT_ID}\" + }" + # encode the JWT payload + payload=$(echo -n "${payload_json}" | b64enc) + + # create the JWT signature + header_payload="${header}"."${payload}" + signature=$( + openssl dgst -sha256 -sign <(echo -n "${PRIVATE_KEY}") \ + <(echo -n "${header_payload}") | b64enc + ) + + # create the JWT + jwt="${header_payload}"."${signature}" + + # get the installation token request URL + installation_token_url=$(curl -L -H "Accept: application/vnd.github+json" -H "Authorization: Bearer $jwt" -H "X-GitHub-Api-Version: 2022-11-28" https://api.github.com/app/installations | jq -r '.[0].access_tokens_url') + if [ -z "$installation_token_url" ] || [ "$installation_token_url" == "null" ]; then + echo "unable to get installation token URL" + exit 1 + fi + + # get the installation token + token=$(curl -X POST -L -H "Accept: application/vnd.github+json" -H "Authorization: Bearer $jwt" -H "X-GitHub-Api-Version: 2022-11-28" "$installation_token_url" | jq -r '.token') + if [ -z "$token" ] || [ "$token" == "null" ]; then + echo "unable to get installation token" + exit 1 + fi + + echo "generated installation token for aks-node-sig-release-assistant" + echo "##vso[task.setvariable variable=GITHUB_TOKEN;issecret=true]$token" + env: + PRIVATE_KEY: $(aks-node-sig-release-assistant-private-key) + CLIENT_ID: $(aks-node-sig-release-assistant-client-id) + displayName: Generate GitHub token \ No newline at end of file diff --git a/vhdbuilder/scripts/automate_helpers.sh b/vhdbuilder/scripts/automate_helpers.sh index dd0397a44a3..6c91222f7db 100644 --- a/vhdbuilder/scripts/automate_helpers.sh +++ b/vhdbuilder/scripts/automate_helpers.sh @@ -1,6 +1,9 @@ #!/bin/bash set -x +RELEASE_ASSISTANT_APP_NAME="aks-node-sig-release-assistant[bot]" +RELEASE_ASSISTANT_APP_UID="190555641" + retrycmd_if_failure() { retries=$1; wait_sleep=$2; shift && shift for i in $(seq 1 $retries); do @@ -18,9 +21,10 @@ retrycmd_if_failure() { } set_git_config() { - # git config needs to be set in the agent - git config --global user.email "aks-node-assistant@microsoft.com" - git config --global user.name "aks-node-assistant" + # git config needs to be set in the agent as the corresponding GitHub app + # https://github.com/orgs/community/discussions/24664#discussioncomment-3244950 + git config --global user.email "${RELEASE_ASSISTANT_APP_UID}+${RELEASE_ASSISTANT_APP_NAME}@users.noreply.github.com" + git config --global user.name "$RELEASE_ASSISTANT_APP_NAME" git config --list } @@ -41,7 +45,7 @@ create_branch() { create_pull_request() { local image_version=$1 - local github_pat=$2 + local github_token=$2 local branch_name=$3 local base_branch=$4 local target=$5 @@ -55,8 +59,10 @@ create_pull_request() { echo "Branch Name is $branch_name" echo "PR is for $target" - set +x # to avoid logging PAT - git remote set-url origin https://${github_pat}@github.com/Azure/AgentBaker.git # Set remote URL with PAT + set +x # to avoid logging token + # use the installation token to authenticate for HTTP-based git access + # https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/authenticating-as-a-github-app-installation#about-authentication-as-a-github-app-installation + git remote set-url origin https://x-access-token:${github_token}@github.com/Azure/AgentBaker.git git add . if [[ "$target" == "ReleaseNotes" ]]; then @@ -69,7 +75,7 @@ create_pull_request() { curl \ -X POST \ - -H "Authorization: Bearer $github_pat" \ + -H "Authorization: Bearer $github_token" \ https://api.github.com/repos/Azure/AgentBaker/pulls \ -d '{ "head" : "'$branch_name'", diff --git a/vhdbuilder/scripts/automate_release_notes.sh b/vhdbuilder/scripts/automate_release_notes.sh index 891bf172a1e..efc39964bc3 100644 --- a/vhdbuilder/scripts/automate_release_notes.sh +++ b/vhdbuilder/scripts/automate_release_notes.sh @@ -3,7 +3,7 @@ set -euo pipefail source vhdbuilder/scripts/automate_helpers.sh set +x -GITHUB_PAT="${GITHUB_PAT:-""}" +GITHUB_TOKEN="${GITHUB_TOKEN:-""}" set -x IMAGE_VERSION="${IMAGE_VERSION:-""}" @@ -42,8 +42,8 @@ if [ -z "$VHD_BUILD_ID" ]; then fi set +x -if [ -z "$GITHUB_PAT" ]; then - echo "GITHUB_PAT must be set to generate release notes" +if [ -z "$GITHUB_TOKEN" ]; then + echo "GITHUB_TOKEN must be set to generate release notes" fi set -x @@ -65,4 +65,4 @@ fi retrycmd_if_failure 5 10 generate_release_notes || exit $? git status set +x -create_pull_request $IMAGE_VERSION $GITHUB_PAT $BRANCH_NAME $PR_TARGET_BRANCH $PR_TITLE \ No newline at end of file +create_pull_request $IMAGE_VERSION $GITHUB_TOKEN $BRANCH_NAME $PR_TARGET_BRANCH $PR_TITLE \ No newline at end of file diff --git a/vhdbuilder/scripts/automate_version_bump.sh b/vhdbuilder/scripts/automate_version_bump.sh index 88fdafe2b46..a42955711a5 100755 --- a/vhdbuilder/scripts/automate_version_bump.sh +++ b/vhdbuilder/scripts/automate_version_bump.sh @@ -3,7 +3,7 @@ set -euxo pipefail source vhdbuilder/scripts/automate_helpers.sh set +x -GITHUB_PAT="${GITHUB_PAT:-""}" +GITHUB_TOKEN="${GITHUB_TOKEN:-""}" set -x NEW_IMAGE_VERSION="${IMAGE_VERSION:-""}" @@ -62,7 +62,7 @@ create_image_bump_pr() { update_image_version set +x - create_pull_request $NEW_IMAGE_VERSION $GITHUB_PAT $BRANCH_NAME $PR_TARGET_BRANCH $PR_TITLE + create_pull_request $NEW_IMAGE_VERSION $GITHUB_TOKEN $BRANCH_NAME $PR_TARGET_BRANCH $PR_TITLE set -x } @@ -109,8 +109,8 @@ cut_official_branch() { } set +x -if [ -z "$GITHUB_PAT" ]; then - echo "GITHUB_PAT must be set in order to bump the image version and create the official branch" +if [ -z "$GITHUB_TOKEN" ]; then + echo "GITHUB_TOKEN must be set in order to bump the image version and create the official branch" exit 1 fi set -x diff --git a/vhdbuilder/scripts/windows/automate_helpers.sh b/vhdbuilder/scripts/windows/automate_helpers.sh index b6f967b74c1..a04299b5012 100644 --- a/vhdbuilder/scripts/windows/automate_helpers.sh +++ b/vhdbuilder/scripts/windows/automate_helpers.sh @@ -1,11 +1,14 @@ #!/bin/bash set -euxo pipefail +RELEASE_ASSISTANT_APP_NAME="aks-node-sig-release-assistant[bot]" +RELEASE_ASSISTANT_APP_UID="190555641" + set_git_config() { - # git config needs to be set in the agent - github_user_name=$1 - git config --global user.email "$github_user_name@microsoft.com" - git config --global user.name "$github_user_name" + # git config needs to be set in the agent as the corresponding GitHub app + # https://github.com/orgs/community/discussions/24664#discussioncomment-3244950 + git config --global user.email "${RELEASE_ASSISTANT_APP_UID}+${RELEASE_ASSISTANT_APP_NAME}@users.noreply.github.com" + git config --global user.name "$RELEASE_ASSISTANT_APP_NAME" git config --list } @@ -91,7 +94,9 @@ create_pull_request() { echo "Branch Name is $branch_name" echo "PR is for $pr_purpose" - git remote set-url origin https://$github_user_name:$github_access_token@github.com/Azure/AgentBaker.git # Set remote URL with PAT + # use the installation token to authenticate for HTTP-based git access + # https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/authenticating-as-a-github-app-installation#about-authentication-as-a-github-app-installation + git remote set-url origin https://x-access-token:${github_access_token}@github.com/Azure/AgentBaker.git git add . if [[ $pr_purpose == "ReleaseNotes" ]]; then diff --git a/vhdbuilder/scripts/windows/automate_release_notes.sh b/vhdbuilder/scripts/windows/automate_release_notes.sh index 4d08c3624be..27d8d0006f3 100644 --- a/vhdbuilder/scripts/windows/automate_release_notes.sh +++ b/vhdbuilder/scripts/windows/automate_release_notes.sh @@ -3,22 +3,20 @@ set -euxo pipefail source vhdbuilder/scripts/windows/automate_helpers.sh -echo "Build Id is $1" - -build_id=$1 - set +x -github_access_token=$2 +github_access_token=$1 set -x -github_user_name=$3 +build_id=$2 +echo "Build Id is $build_id" + image_version=$(date +"%Y-%m") -branch_name=$github_user_name/win-${image_version}b-release-notes +branch_name=releaseNotes/win-${image_version}b-release-notes pr_purpose="ReleaseNotes" -set_git_config $github_user_name +set_git_config if [ `git branch --list $branch_name` ]; then git checkout $branch_name git pull origin diff --git a/vhdbuilder/scripts/windows/automate_version_bump.sh b/vhdbuilder/scripts/windows/automate_version_bump.sh index d746a554d04..7a3eddf65a0 100644 --- a/vhdbuilder/scripts/windows/automate_version_bump.sh +++ b/vhdbuilder/scripts/windows/automate_version_bump.sh @@ -1,7 +1,6 @@ #!/bin/bash set -euxo pipefail -github_user_name=$2 source vhdbuilder/scripts/windows/automate_helpers.sh az login --identity @@ -14,7 +13,7 @@ set +x github_access_token=$1 set -x -cherry_pick_commit_id=$3 +cherry_pick_commit_id=$2 # This function finds the latest windows VHD base Image version from the command az vm image show find_latest_image_version() { @@ -29,7 +28,7 @@ find_latest_image_version() { echo "Latest windows 23H2 base image version is ${latest_image_version_23H2}" echo "Latest windows 23H2 Gen 2 base image version is: ${latest_image_version_23H2_g2}" new_image_version=$(date +"%Y-%m") - branch_name=$github_user_name/win-${new_image_version}b + branch_name=imageBump/win-${new_image_version}b } # This function replaces the old Windows 2019 & Windows 2022 (gen1/gen2) base image version with the latest version found by az vm image show in windows-image.env @@ -75,6 +74,6 @@ create_image_bump_pr() { set -x } -set_git_config $github_user_name +set_git_config find_latest_image_version create_image_bump_pr