From 22c1b9c3046de555a016cb7bd6097365c31dc93d Mon Sep 17 00:00:00 2001 From: Marika Marszalkowski Date: Thu, 2 Apr 2026 08:45:31 +0200 Subject: [PATCH 1/7] chore: Use GH app instead of PAT --- .../workflows/cache-maven-dependencies.yaml | 19 +- .github/workflows/dependabot-automerge.yaml | 24 ++- .github/workflows/fosstars-report.yml | 32 ++-- .github/workflows/perform-release.yaml | 75 +++++--- .github/workflows/prepare-release.yaml | 165 ++++++++++-------- .github/workflows/spec-update.yaml | 18 +- .../workflows/weekly-spec-update-cleanup.yaml | 2 + 7 files changed, 195 insertions(+), 140 deletions(-) diff --git a/.github/workflows/cache-maven-dependencies.yaml b/.github/workflows/cache-maven-dependencies.yaml index 5ec5bcff8..57691fcfa 100644 --- a/.github/workflows/cache-maven-dependencies.yaml +++ b/.github/workflows/cache-maven-dependencies.yaml @@ -1,11 +1,12 @@ -name: "Cache Maven Dependencies" +name: 'Cache Maven Dependencies' permissions: contents: read + actions: write on: workflow_dispatch: schedule: - - cron: '57 4 * * Sun' + - cron: '57 4 * * Sun' env: MAVEN_CACHE_REF: refs/heads/main @@ -16,21 +17,21 @@ jobs: update-cache: runs-on: ubuntu-latest steps: - - name: "Checkout" + - name: 'Checkout' uses: actions/checkout@v6 with: ref: ${{ env.MAVEN_CACHE_REF }} - - name: "Setup Java" + - name: 'Setup Java' uses: actions/setup-java@v5 with: - distribution: "sapmachine" + distribution: 'sapmachine' java-version: 21 - - name: "Download Dependencies" + - name: 'Download Dependencies' run: mvn -B dependency:go-offline - - name: "Delete Existing Caches" + - name: 'Delete Existing Caches' run: | CACHE_IDS=$(gh cache list --key "${{ env.MAVEN_CACHE_KEY }}" --ref "${{ env.MAVEN_CACHE_REF }}" --json id | jq -r '.[] | .id') for CACHE_ID in $CACHE_IDS; do @@ -38,9 +39,9 @@ jobs: gh cache delete "${CACHE_ID}" done env: - GH_TOKEN: ${{ secrets.BOT_SDK_JS_FOR_DOCS_REPO_PR }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: "Cache Dependencies" + - name: 'Cache Dependencies' uses: actions/cache/save@v5 with: path: ${{ env.MAVEN_CACHE_DIR }} diff --git a/.github/workflows/dependabot-automerge.yaml b/.github/workflows/dependabot-automerge.yaml index a19450a76..ebf418bc3 100644 --- a/.github/workflows/dependabot-automerge.yaml +++ b/.github/workflows/dependabot-automerge.yaml @@ -1,4 +1,4 @@ -name: "Dependabot Auto-Merge" +name: 'Dependabot Auto-Merge' on: workflow_dispatch: @@ -14,14 +14,22 @@ env: jobs: review-prs: runs-on: ubuntu-latest - permissions: - pull-requests: write - contents: write steps: + - name: Generate GitHub App token + id: app-token + uses: actions/create-github-app-token@v3 + with: + app-id: ${{ secrets.SAP_AI_SDK_BOT_CLIENT_ID }} + private-key: ${{ secrets.SAP_AI_SDK_BOT_PRIVATE_KEY }} + permission-contents: write + permission-pull-requests: write + - name: Checkout uses: actions/checkout@v6 - name: Approve and Merge PRs + env: + GH_TOKEN: ${{ steps.app-token.outputs.token }} run: | PRS=$(gh pr list --app "dependabot" --state "open" --json number,title) PR_NUMBERS= @@ -29,14 +37,14 @@ jobs: if [[ -z "$GROUP" ]]; then continue fi - + MATCHES=$(jq -r --arg group "$GROUP" '.[] | select(.title | contains($group)) | .number' <<< "$PRS") echo "[DEBUG] Found PRs for group '$GROUP': '$MATCHES'" - + PR_NUMBERS="$MATCHES"$'\n'"$PR_NUMBERS" done <<< "${{ env.DEPENDABOT_GROUPS }}" echo "[DEBUG] Approving and Merging following PRs: '$PR_NUMBERS'" - + while IFS= read -r PR_NUMBER; do if [[ -z "$PR_NUMBER" ]]; then continue @@ -46,5 +54,3 @@ jobs: gh pr merge "$PR_NUMBER" --auto --squash gh pr review "$PR_NUMBER" --approve done <<< "$PR_NUMBERS" - env: - GH_TOKEN: ${{ secrets.BOT_SDK_JS_FOR_DOCS_REPO_PR }} diff --git a/.github/workflows/fosstars-report.yml b/.github/workflows/fosstars-report.yml index b49f5cd69..d813df2a3 100644 --- a/.github/workflows/fosstars-report.yml +++ b/.github/workflows/fosstars-report.yml @@ -1,4 +1,4 @@ -name: "Fosstars (Security)" +name: 'Fosstars (Security)' on: workflow_dispatch: schedule: @@ -13,53 +13,53 @@ env: jobs: create_fosstars_report: - name: "Security rating" + name: 'Security rating' runs-on: ubuntu-latest permissions: - contents: read + contents: write actions: write steps: - - name: "Checkout repository" + - name: 'Checkout repository' uses: actions/checkout@v6 - - name: "Setup java" + - name: 'Setup java' uses: actions/setup-java@v5 with: - distribution: "sapmachine" + distribution: 'sapmachine' java-version: ${{ env.JAVA_VERSION }} cache: 'maven' - - name: "Restore CVE Database" + - name: 'Restore CVE Database' uses: actions/cache/restore@v5 with: path: ${{ env.CVE_CACHE_DIR }} key: ${{ env.CVE_CACHE_KEY }} - # fail-on-cache-miss: true + # fail-on-cache-miss: true - - name: "Build SDK" + - name: 'Build SDK' run: | MVN_ARGS="${{ env.MVN_MULTI_THREADED_ARGS }} clean install -DskipTests -DskipFormatting" mvn $MVN_ARGS - - name: "Create settings.xml" + - name: 'Create settings.xml' run: | echo '${{ secrets.OSS_INDEX_SETTINGS_XML }}' > settings.xml - - name: "CVE Scan" + - name: 'CVE Scan' env: NVD_API_KEY: ${{ secrets.NVD_API_KEY }} run: > mvn -T1 --no-transfer-progress -s settings.xml --batch-mode org.owasp:dependency-check-maven:check org.owasp:dependency-check-maven:aggregate - - name: "Archive CVE Report" + - name: 'Archive CVE Report' uses: actions/upload-artifact@v7 with: name: cve-report path: target/dependency-check-report.html retention-days: 7 - - name: "Delete Old CVE Cache" + - name: 'Delete Old CVE Cache' run: | CACHE_IDS=$(gh cache list --key "${{ env.CVE_CACHE_KEY }}" --ref "${{ env.CVE_CACHE_REF }}" --json id | jq -r '.[] | .id') for CACHE_ID in $CACHE_IDS; do @@ -69,20 +69,20 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: "Create Updated CVE Cache" + - name: 'Create Updated CVE Cache' uses: actions/cache/save@v5 with: path: ${{ env.CVE_CACHE_DIR }} key: ${{ env.CVE_CACHE_KEY }} # This action changes the active branch! - - name: "Fosstars Rating" + - name: 'Fosstars Rating' uses: SAP/fosstars-rating-core-action@v1.14.0 with: report-branch: fosstars-report token: ${{ secrets.GITHUB_TOKEN }} - - name: "Slack Notification" + - name: 'Slack Notification' if: failure() uses: slackapi/slack-github-action@v2.1.1 with: diff --git a/.github/workflows/perform-release.yaml b/.github/workflows/perform-release.yaml index 7be8293b3..c189753bb 100644 --- a/.github/workflows/perform-release.yaml +++ b/.github/workflows/perform-release.yaml @@ -1,13 +1,13 @@ -name: "Perform Release" +name: 'Perform Release' on: workflow_dispatch: inputs: release_pr_number: - description: "The PR number of the release PR" + description: 'The PR number of the release PR' required: true skip-pr-merge: - description: "Whether to skip merging the PRs" + description: 'Whether to skip merging the PRs' required: false default: false type: boolean @@ -19,7 +19,7 @@ env: jobs: prerequisites: - name: "Prerequisites" + name: 'Prerequisites' outputs: code-branch: ${{ steps.determine-branch-names.outputs.CODE_BRANCH_NAME }} release-notes-branch: ${{ steps.determine-branch-names.outputs.RELEASE_NOTES_BRANCH_NAME }} @@ -28,7 +28,7 @@ jobs: permissions: write-all # contents and push are needed to see the draft release runs-on: ubuntu-latest steps: - - name: "Determine Branch Names" + - name: 'Determine Branch Names' id: determine-branch-names run: | CODE_BRANCH_NAME=$(gh pr view ${{github.event.inputs.release_pr_number}} --repo ${{github.repository}} --json headRefName --jq '.headRefName') @@ -36,21 +36,29 @@ jobs: RELEASE_TAG=rel/$RELEASE_VERSION RELEASE_COMMIT=$(gh release view $RELEASE_TAG --repo ${{github.repository}} --json targetCommitish --jq '.targetCommitish') RELEASE_NOTES_BRANCH_NAME=java/release-notes-$RELEASE_VERSION - + echo "CODE_BRANCH_NAME=$CODE_BRANCH_NAME" >> $GITHUB_OUTPUT echo "RELEASE_VERSION=$RELEASE_VERSION" >> $GITHUB_OUTPUT echo "RELEASE_TAG=$RELEASE_TAG" >> $GITHUB_OUTPUT echo "RELEASE_COMMIT=$RELEASE_COMMIT" >> $GITHUB_OUTPUT echo "RELEASE_NOTES_BRANCH_NAME=$RELEASE_NOTES_BRANCH_NAME" >> $GITHUB_OUTPUT - + echo -e "[DEBUG] Current GITHUB_OUTPUT:\n$(cat $GITHUB_OUTPUT)" env: GH_TOKEN: ${{ github.token }} - - name: "Checkout Repository" + - name: 'Generate GitHub App token' + id: app-token + uses: actions/create-github-app-token@v3 + with: + app-id: ${{ secrets.SAP_AI_SDK_BOT_CLIENT_ID }} + private-key: ${{ secrets.SAP_AI_SDK_BOT_PRIVATE_KEY }} + owner: ${{ github.repository_owner }} + + - name: 'Checkout Repository' uses: actions/checkout@v6 - - name: "Check Whether Code PR Can Be Merged" + - name: 'Check Whether Code PR Can Be Merged' if: ${{ inputs.skip-pr-merge != 'true' }} uses: ./.github/actions/pr-is-mergeable with: @@ -61,40 +69,49 @@ jobs: \"dependabot merger\": [] } - - name: "Check Code Release Commit Continuous Integration" + - name: 'Check Code Release Commit Continuous Integration' if: ${{ inputs.skip-pr-merge != 'true' }} uses: ./.github/actions/workflow-succeeded with: - workflow: "Continuous Integration" + workflow: 'Continuous Integration' sha: ${{ steps.determine-branch-names.outputs.RELEASE_COMMIT }} - - name: "Check Whether Release Notes PR Can Be Merged" + - name: 'Check Whether Release Notes PR Can Be Merged' if: ${{ inputs.skip-pr-merge != 'true' }} uses: ./.github/actions/pr-is-mergeable with: pr-ref: ${{ steps.determine-branch-names.outputs.RELEASE_NOTES_BRANCH_NAME }} repo: ${{ env.DOCS_REPO }} - token: ${{ secrets.BOT_SDK_JS_FOR_DOCS_REPO_PR }} + token: ${{ steps.app-token.outputs.token }} excluded-check-runs: | { \"Build Cloud SDK Documentation\": [\"dependabot\"] } release: - name: "Release" - needs: [ prerequisites ] + name: 'Release' + needs: [prerequisites] runs-on: ubuntu-latest permissions: - contents: write # needed to modify the release draft - pull-requests: write # needed to merge the release PR + contents: read steps: - - name: "Setup java" + - name: 'Generate GitHub App token' + id: app-token + uses: actions/create-github-app-token@v3 + with: + app-id: ${{ secrets.SAP_AI_SDK_BOT_CLIENT_ID }} + private-key: ${{ secrets.SAP_AI_SDK_BOT_PRIVATE_KEY }} + owner: ${{ github.repository_owner }} + permission-contents: write # needed to modify the release draft + permission-pull-requests: write # needed to merge the release PR + + - name: 'Setup java' uses: actions/setup-java@v5 with: - distribution: "sapmachine" + distribution: 'sapmachine' java-version: ${{ env.JAVA_VERSION }} - - name: "Download Release Asset" + - name: 'Download Release Asset' id: download-asset run: | gh release download ${{ needs.prerequisites.outputs.release-tag }} --dir ./ --repo "${{ github.repository }}" @@ -103,36 +120,36 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: "Import GPG Key" + - name: 'Import GPG Key' run: | echo "${{ secrets.PGP_PRIVATE_KEY }}" | gpg --batch --passphrase "$PASSPHRASE" --import env: PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }} - - name: "Create settings.xml" + - name: 'Create settings.xml' run: | echo '${{ secrets.CENTRAL_SONATYPE_SETTINGS_XML }}' > settings.xml - - name: "Deploy" + - name: 'Deploy' run: | MVN_ARGS="${{ env.MVN_CLI_ARGS }} -Drelease -s settings.xml" mvn deploy $MVN_ARGS env: MAVEN_GPG_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }} - - name: "Merge Code PR" + - name: 'Merge Code PR' if: ${{ inputs.skip-pr-merge != 'true' }} run: gh pr merge --squash "${{ needs.prerequisites.outputs.code-branch }}" --delete-branch --repo "${{ github.repository }}" env: - GH_TOKEN: ${{ secrets.BOT_SDK_JS_FOR_DOCS_REPO_PR }} + GH_TOKEN: ${{ steps.app-token.outputs.token }} - - name: "Publish the Draft Release" + - name: 'Publish the Draft Release' run: gh release edit ${{ needs.prerequisites.outputs.release-tag }} --draft=false --repo "${{ github.repository }}" env: - GH_TOKEN: ${{ secrets.BOT_SDK_JS_FOR_DOCS_REPO_PR }} + GH_TOKEN: ${{ steps.app-token.outputs.token }} - - name: "Merge Release Notes PR" + - name: 'Merge Release Notes PR' if: ${{ inputs.skip-pr-merge != 'true' }} run: gh pr merge --squash "${{ needs.prerequisites.outputs.release-notes-branch }}" --delete-branch --repo "${{ env.DOCS_REPO }}" env: - GH_TOKEN: ${{ secrets.BOT_SDK_JS_FOR_DOCS_REPO_PR }} + GH_TOKEN: ${{ steps.app-token.outputs.token }} diff --git a/.github/workflows/prepare-release.yaml b/.github/workflows/prepare-release.yaml index 018e65025..30c1cbef8 100644 --- a/.github/workflows/prepare-release.yaml +++ b/.github/workflows/prepare-release.yaml @@ -1,25 +1,25 @@ -name: "Prepare Release" +name: 'Prepare Release' on: workflow_dispatch: inputs: branch: - description: "The Branch to Release From" + description: 'The Branch to Release From' required: false - default: "main" + default: 'main' release-version: - description: "The Version to Release" + description: 'The Version to Release' required: false env: - CI_BUILD_WORKFLOW: "continuous-integration.yaml" # Name of the workflow that should be triggered for CI build + CI_BUILD_WORKFLOW: 'continuous-integration.yaml' # Name of the workflow that should be triggered for CI build MVN_MULTI_THREADED_ARGS: --batch-mode --no-transfer-progress --fail-at-end --show-version --threads 1C JAVA_VERSION: 21 DOCS_REPO: SAP/ai-sdk jobs: bump-version: - name: "Bump Version" + name: 'Bump Version' outputs: current-version: ${{ steps.determine-versions.outputs.CURRENT_SNAPSHOT }} release-version: ${{ steps.determine-versions.outputs.RELEASE_VERSION }} @@ -31,27 +31,27 @@ jobs: permissions: contents: write steps: - - name: "Checkout Repository" + - name: 'Checkout Repository' uses: actions/checkout@v6 with: ref: ${{ github.event.inputs.branch }} - - name: "Prepare git" + - name: 'Prepare git' run: | git config --global user.email "cloudsdk@sap.com" git config --global user.name "SAP Cloud SDK Bot" - - name: "Determine Versions" + - name: 'Determine Versions' id: determine-versions run: python .pipeline/scripts/get-release-versions.py env: INPUT_VERSION: ${{ github.event.inputs.release-version }} - - run: "echo Release Version: ${{ steps.determine-versions.outputs.RELEASE_VERSION }}" - - run: "echo Current Version: ${{ steps.determine-versions.outputs.CURRENT_SNAPSHOT }}" - - run: "echo New Version: ${{ steps.determine-versions.outputs.NEW_SNAPSHOT }}" + - run: 'echo Release Version: ${{ steps.determine-versions.outputs.RELEASE_VERSION }}' + - run: 'echo Current Version: ${{ steps.determine-versions.outputs.CURRENT_SNAPSHOT }}' + - run: 'echo New Version: ${{ steps.determine-versions.outputs.NEW_SNAPSHOT }}' - - name: "Set Release Version to ${{ steps.determine-versions.outputs.RELEASE_VERSION }}" + - name: 'Set Release Version to ${{ steps.determine-versions.outputs.RELEASE_VERSION }}' id: prepare-release run: | # NOTE: If you change this pattern here, also adjust perform_release.yml: @@ -66,7 +66,7 @@ jobs: # We need to get the commit id, and push the branch so the release tag will point at the right commit afterwards RELEASE_COMMIT_ID=$(git log -1 --pretty=format:"%H") echo "RELEASE_COMMIT_ID=$RELEASE_COMMIT_ID" >> $GITHUB_OUTPUT - + TAG_NAME=rel/${{ steps.determine-versions.outputs.RELEASE_VERSION }} git tag $TAG_NAME $RELEASE_COMMIT_ID echo "TAG_NAME=$TAG_NAME" >> $GITHUB_OUTPUT @@ -75,21 +75,21 @@ jobs: git push origin $TAG_NAME run-ci: - name: "Continuous Integration" + name: 'Continuous Integration' outputs: ci-run-id: ${{ steps.trigger-ci.outputs.run-id }} - needs: [ bump-version ] + needs: [bump-version] runs-on: ubuntu-latest permissions: actions: write # needed to trigger the ci-build workflow statuses: write # needed to update the commit status steps: - - name: "Checkout repository" + - name: 'Checkout repository' uses: actions/checkout@v6 with: ref: ${{ needs.bump-version.outputs.release-branch }} - - name: "Trigger CI Workflow" + - name: 'Trigger CI Workflow' id: trigger-ci uses: ./.github/actions/trigger-workflow with: @@ -97,15 +97,15 @@ jobs: workflow-ref: ${{ needs.bump-version.outputs.release-branch }} commit-sha: ${{ needs.bump-version.outputs.release-commit }} - - name: "Await CI Workflow" + - name: 'Await CI Workflow' uses: ./.github/actions/await-workflow with: run-id: ${{ steps.trigger-ci.outputs.run-id }} - commit-status: "Continuous Integration Workflow" + commit-status: 'Continuous Integration Workflow' create-release: - name: "Create GitHub Release" - needs: [ bump-version, run-ci ] + name: 'Create GitHub Release' + needs: [bump-version, run-ci] outputs: release-name: ${{ steps.create-release.outputs.RELEASE_NAME }} release-url: ${{ steps.create-release.outputs.RELEASE_URL }} @@ -114,24 +114,24 @@ jobs: actions: read # needed to download the artifacts from the CI workflow runs-on: ubuntu-latest steps: - - name: "Checkout repository" + - name: 'Checkout repository' uses: actions/checkout@v6 with: ref: ${{ needs.bump-version.outputs.release-branch }} - - name: "Setup java" + - name: 'Setup java' uses: actions/setup-java@v5 with: - distribution: "sapmachine" + distribution: 'sapmachine' java-version: ${{ env.JAVA_VERSION }} cache: 'maven' - - name: "Build SDK" + - name: 'Build SDK' run: | MVN_ARGS="${{ env.MVN_MULTI_THREADED_ARGS }} clean install -DskipTests" mvn $MVN_ARGS - - name: "Create Release" + - name: 'Create Release' id: create-release run: | # Create a tarball of the whole repository into release-artifacts.tar.gz @@ -139,63 +139,69 @@ jobs: RELEASE_NAME="rel/${{ needs.bump-version.outputs.release-version }}" echo "RELEASE_NAME=$RELEASE_NAME" >> $GITHUB_OUTPUT - + RELEASE_URL=$(gh release create "$RELEASE_NAME" \ --target ${{ needs.bump-version.outputs.release-commit }} \ --title "Release ${{ needs.bump-version.outputs.release-version }}" \ --draft --generate-notes \ release-artifacts.tar.gz) - + echo "RELEASE_URL=$RELEASE_URL" >> $GITHUB_OUTPUT env: GH_TOKEN: ${{ github.token }} - create-release-notes-pr: - name: "Create Release Notes PR" - needs: [ bump-version, run-ci ] + name: 'Create Release Notes PR' + needs: [bump-version, run-ci] outputs: pr-url: ${{ steps.create-release-notes-pr.outputs.PR_URL }} runs-on: ubuntu-latest - permissions: - contents: write - pull-requests: write steps: - - name: "Checkout Code Repository" + - name: 'Generate GitHub App token' + id: app-token + uses: actions/create-github-app-token@v3 + with: + app-id: ${{ secrets.SAP_AI_SDK_BOT_CLIENT_ID }} + private-key: ${{ secrets.SAP_AI_SDK_BOT_PRIVATE_KEY }} + owner: ${{ github.repository_owner }} + permission-contents: write + permission-pull-requests: write + + - name: 'Checkout Code Repository' uses: actions/checkout@v6 with: ref: ${{ needs.bump-version.outputs.release-branch }} - token: ${{ secrets.BOT_SDK_JS_FOR_DOCS_REPO_PR }} - - name: "Checkout Docs Repository" + token: ${{ steps.app-token.outputs.token }} + - name: 'Checkout Docs Repository' uses: actions/checkout@v6 with: repository: ${{ env.DOCS_REPO }} path: .ai-sdk-docs - token: ${{ secrets.BOT_SDK_JS_FOR_DOCS_REPO_PR }} - - name: "Prepare Git" + token: ${{ steps.app-token.outputs.token }} + - name: 'Prepare Git' working-directory: ./.ai-sdk-docs run: | git config --global user.email "cloudsdk@sap.com" git config --global user.name "SAP Cloud SDK Bot" - - name: "Create Release Notes Branch" + - name: 'Create Release Notes Branch' working-directory: ./.ai-sdk-docs run: git checkout -B java/release-notes-${{ needs.bump-version.outputs.release-version }} - - name: "Create Release Notes" + - name: 'Create Release Notes' run: python .pipeline/scripts/release_notes_automation.py --version ${{ needs.bump-version.outputs.release-version }} --folder ".ai-sdk-docs/docs-java/release-notes" - - name: "Commit Release Notes" + - name: 'Commit Release Notes' working-directory: ./.ai-sdk-docs run: | git add . git commit -m "Add new release notes" - - name: "Push Release Notes" + - name: 'Push Release Notes' working-directory: ./.ai-sdk-docs run: git push origin java/release-notes-${{ needs.bump-version.outputs.release-version }} - - name: "Create Release Notes PR" + - name: 'Create Release Notes PR' id: create-release-notes-pr working-directory: ./.ai-sdk-docs run: | @@ -214,9 +220,9 @@ jobs: PR_URL=$(gh pr create --title "$PR_TITLE" --body "$PR_BODY" --repo "${{ env.DOCS_REPO }}") echo "PR_URL=$PR_URL" >> $GITHUB_OUTPUT env: - GH_TOKEN: ${{ secrets.BOT_SDK_JS_FOR_DOCS_REPO_PR }} + GH_TOKEN: ${{ steps.app-token.outputs.token }} - - name: "Reset Release Notes for Next Version" + - name: 'Reset Release Notes for Next Version' run: | rm -rf .ai-sdk-docs @@ -233,36 +239,42 @@ jobs: git push create-code-pr: - name: "Create Code PR" - needs: [ bump-version, run-ci, create-release, create-release-notes-pr ] + name: 'Create Code PR' + needs: [bump-version, run-ci, create-release, create-release-notes-pr] outputs: pr-url: ${{ steps.create-code-pr.outputs.PR_URL }} runs-on: ubuntu-latest - permissions: - contents: write - pull-requests: write steps: - - name: "Checkout Repository" + - name: 'Generate GitHub App token' + id: app-token + uses: actions/create-github-app-token@v3 + with: + app-id: ${{ secrets.SAP_AI_SDK_BOT_CLIENT_ID }} + private-key: ${{ secrets.SAP_AI_SDK_BOT_PRIVATE_KEY }} + permission-contents: write + permission-pull-requests: write + + - name: 'Checkout Repository' uses: actions/checkout@v6 with: ref: ${{ needs.bump-version.outputs.release-branch }} - token: ${{ secrets.BOT_SDK_JS_FOR_DOCS_REPO_PR }} # this is needed so that the same token is used when pushing our changes later. Otherwise, our on: push workflows (i.e. our continuous integration) won't be triggered. - - name: "Prepare Git" + token: ${{ steps.app-token.outputs.token }} # this is needed so that the same token is used when pushing our changes later. Otherwise, our on: push workflows (i.e. our continuous integration) won't be triggered. + - name: 'Prepare Git' run: | git config --global user.email "cloudsdk@sap.com" git config --global user.name "SAP Cloud SDK Bot" - - name: "Set New Version" + - name: 'Set New Version' run: | python .pipeline/scripts/set-release-versions.py --version ${{ needs.bump-version.outputs.new-version }} git add . git commit -m "Update to version ${{ needs.bump-version.outputs.new-version }}" git push - - name: "Create Code PR" + - name: 'Create Code PR' run: | COMMIT_URL=${{ github.event.repository.html_url }}/commit/${{ needs.bump-version.outputs.release-commit }} - + PR_URL=$(gh pr create --title "feat: Release ${{ needs.bump-version.outputs.release-version }}" --body "## TODOs - [ ] Review the changes in [the release commit]($COMMIT_URL) - [ ] Review **and approve** the [Release Notes PR](${{ needs.create-release-notes-pr.outputs.pr-url }}) @@ -272,49 +284,60 @@ jobs: - [ ] Once the `Perform Release` workflow is through, head over to the [Central Sonatype](https://central.sonatype.com/publishing/deployments) and log in with the credentials in the Team Password Safe. There should be a published release.") echo "PR_URL=$PR_URL" >> $GITHUB_OUTPUT env: - GH_TOKEN: ${{ secrets.BOT_SDK_JS_FOR_DOCS_REPO_PR }} + GH_TOKEN: ${{ steps.app-token.outputs.token }} handle-failure: runs-on: ubuntu-latest - needs: [ bump-version, create-release, create-release-notes-pr, create-code-pr ] + needs: + [bump-version, create-release, create-release-notes-pr, create-code-pr] permissions: - contents: write # needed to delete the GitHub release + contents: read if: ${{ failure() }} steps: - - name: "Checkout Repository" + - name: 'Generate GitHub App token' + id: app-token + uses: actions/create-github-app-token@v3 + with: + app-id: ${{ secrets.SAP_AI_SDK_BOT_CLIENT_ID }} + private-key: ${{ secrets.SAP_AI_SDK_BOT_PRIVATE_KEY }} + owner: ${{ github.repository_owner }} + permission-contents: write + permission-pull-requests: write + + - name: 'Checkout Repository' uses: actions/checkout@v6 with: ref: ${{ github.event.inputs.branch }} - - name: "Prepare git" + - name: 'Prepare git' run: | git config --global user.email "cloudsdk@sap.com" git config --global user.name "SAP Cloud SDK Bot" - - name: "Delete Release" + - name: 'Delete Release' if: ${{ needs.create-release.outputs.release-url != '' }} run: gh release delete --repo "${{ github.repository }}" ${{ needs.create-release.outputs.release-name }} --yes env: - GH_TOKEN: ${{ secrets.BOT_SDK_JS_FOR_DOCS_REPO_PR }} + GH_TOKEN: ${{ steps.app-token.outputs.token }} continue-on-error: true - - name: "Delete Release Branch" + - name: 'Delete Release Branch' if: ${{ needs.bump-version.outputs.release-branch != '' }} run: git push --delete origin ${{ needs.bump-version.outputs.release-branch }} env: - GITHUB_TOKEN: ${{ secrets.BOT_SDK_JS_FOR_DOCS_REPO_PR }} + GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} continue-on-error: true - - name: "Delete Release Tag" + - name: 'Delete Release Tag' if: ${{ needs.bump-version.outputs.release-tag != '' }} run: git push --delete origin ${{ needs.bump-version.outputs.release-tag }} env: - GITHUB_TOKEN: ${{ secrets.BOT_SDK_JS_FOR_DOCS_REPO_PR }} + GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} continue-on-error: true - - name: "Delete Release Notes PR" + - name: 'Delete Release Notes PR' if: ${{ needs.create-release-notes-pr.outputs.pr-url != '' }} run: gh pr close --repo "${{ env.DOCS_REPO }}" ${{ needs.create-release-notes-pr.outputs.pr-url }} --delete-branch env: - GH_TOKEN: ${{ secrets.BOT_SDK_JS_FOR_DOCS_REPO_PR }} + GH_TOKEN: ${{ steps.app-token.outputs.token }} continue-on-error: true diff --git a/.github/workflows/spec-update.yaml b/.github/workflows/spec-update.yaml index bf7b6adb6..05254e88f 100644 --- a/.github/workflows/spec-update.yaml +++ b/.github/workflows/spec-update.yaml @@ -47,9 +47,6 @@ jobs: generate: name: 'Download, Generate, Compile and Push' runs-on: [ubuntu-latest] - permissions: - pull-requests: write - contents: write outputs: spec_diff: ${{ steps.spec_diff.outputs.spec_diff }} branch: ${{ steps.push.outputs.branch }} @@ -62,10 +59,19 @@ jobs: REF: ${{ github.event.inputs.ref }} CREATE_PR: ${{ github.event.inputs.create-pr }} steps: + - name: 'Generate GitHub App token' + id: app-token + uses: actions/create-github-app-token@v3 + with: + app-id: ${{ secrets.SAP_AI_SDK_BOT_CLIENT_ID }} + private-key: ${{ secrets.SAP_AI_SDK_BOT_PRIVATE_KEY }} + permission-contents: write + permission-pull-requests: write + - name: 'Checkout repository' uses: actions/checkout@v6 with: - token: ${{ secrets.BOT_SDK_JS_FOR_DOCS_REPO_PR }} + token: ${{ steps.app-token.outputs.token }} - name: 'Determine PR base' id: pr_base @@ -154,7 +160,7 @@ jobs: - name: 'Exit if there are no spec changes' id: spec_diff env: - GH_TOKEN: ${{ secrets.BOT_SDK_JS_FOR_DOCS_REPO_PR }} + GH_TOKEN: ${{ steps.app-token.outputs.token }} run: | # if there are no spec changes in this commit, check if previous run on this branch is red. If it is red, exit 1; if it is green, exit 0. if [[ `git status --porcelain` ]]; then @@ -239,7 +245,7 @@ jobs: id: create-pr if: ${{ env.CREATE_PR == 'true' && steps.spec_diff.outputs.spec_diff == 'true'}} env: - GH_TOKEN: ${{ secrets.BOT_SDK_JS_FOR_DOCS_REPO_PR }} + GH_TOKEN: ${{ steps.app-token.outputs.token }} BRANCH: ${{ steps.branch.outputs.branch }} BASE: ${{ steps.pr_base.outputs.BASE }} run: | diff --git a/.github/workflows/weekly-spec-update-cleanup.yaml b/.github/workflows/weekly-spec-update-cleanup.yaml index fa7f77172..419db3915 100644 --- a/.github/workflows/weekly-spec-update-cleanup.yaml +++ b/.github/workflows/weekly-spec-update-cleanup.yaml @@ -9,6 +9,8 @@ jobs: find-stale-branches: name: 'Find stale spec-update branches' runs-on: ubuntu-latest + permissions: + contents: read outputs: branches: ${{ steps.list.outputs.branches }} steps: From cebfbc876292e2ab5b42a7baee9141e43d176310 Mon Sep 17 00:00:00 2001 From: Marika Marszalkowski Date: Thu, 2 Apr 2026 10:06:35 +0200 Subject: [PATCH 2/7] restrict further --- .github/workflows/dependabot-automerge.yaml | 2 +- .github/workflows/perform-release.yaml | 9 ++++++++- .github/workflows/prepare-release.yaml | 10 +++++++++- .github/workflows/spec-update.yaml | 3 +++ .github/workflows/weekly-spec-update.yaml | 1 + 5 files changed, 22 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dependabot-automerge.yaml b/.github/workflows/dependabot-automerge.yaml index ebf418bc3..36edb5956 100644 --- a/.github/workflows/dependabot-automerge.yaml +++ b/.github/workflows/dependabot-automerge.yaml @@ -21,7 +21,7 @@ jobs: with: app-id: ${{ secrets.SAP_AI_SDK_BOT_CLIENT_ID }} private-key: ${{ secrets.SAP_AI_SDK_BOT_PRIVATE_KEY }} - permission-contents: write + repositories: ai-sdk-java permission-pull-requests: write - name: Checkout diff --git a/.github/workflows/perform-release.yaml b/.github/workflows/perform-release.yaml index c189753bb..8a0df93b0 100644 --- a/.github/workflows/perform-release.yaml +++ b/.github/workflows/perform-release.yaml @@ -25,7 +25,9 @@ jobs: release-notes-branch: ${{ steps.determine-branch-names.outputs.RELEASE_NOTES_BRANCH_NAME }} release-tag: ${{ steps.determine-branch-names.outputs.RELEASE_TAG }} release-commit: ${{ steps.determine-branch-names.outputs.RELEASE_COMMIT }} - permissions: write-all # contents and push are needed to see the draft release + permissions: + contents: read + pull-requests: read runs-on: ubuntu-latest steps: - name: 'Determine Branch Names' @@ -54,6 +56,8 @@ jobs: app-id: ${{ secrets.SAP_AI_SDK_BOT_CLIENT_ID }} private-key: ${{ secrets.SAP_AI_SDK_BOT_PRIVATE_KEY }} owner: ${{ github.repository_owner }} + repositories: ai-sdk + permission-pull-requests: read - name: 'Checkout Repository' uses: actions/checkout@v6 @@ -102,6 +106,9 @@ jobs: app-id: ${{ secrets.SAP_AI_SDK_BOT_CLIENT_ID }} private-key: ${{ secrets.SAP_AI_SDK_BOT_PRIVATE_KEY }} owner: ${{ github.repository_owner }} + repositories: | + ai-sdk-java + ai-sdk permission-contents: write # needed to modify the release draft permission-pull-requests: write # needed to merge the release PR diff --git a/.github/workflows/prepare-release.yaml b/.github/workflows/prepare-release.yaml index 30c1cbef8..ceb797b7a 100644 --- a/.github/workflows/prepare-release.yaml +++ b/.github/workflows/prepare-release.yaml @@ -111,7 +111,6 @@ jobs: release-url: ${{ steps.create-release.outputs.RELEASE_URL }} permissions: contents: write # needed to create a new release - actions: read # needed to download the artifacts from the CI workflow runs-on: ubuntu-latest steps: - name: 'Checkout repository' @@ -156,6 +155,7 @@ jobs: outputs: pr-url: ${{ steps.create-release-notes-pr.outputs.PR_URL }} runs-on: ubuntu-latest + permissions: {} steps: - name: 'Generate GitHub App token' id: app-token @@ -164,6 +164,9 @@ jobs: app-id: ${{ secrets.SAP_AI_SDK_BOT_CLIENT_ID }} private-key: ${{ secrets.SAP_AI_SDK_BOT_PRIVATE_KEY }} owner: ${{ github.repository_owner }} + repositories: | + ai-sdk-java + ai-sdk permission-contents: write permission-pull-requests: write @@ -244,6 +247,7 @@ jobs: outputs: pr-url: ${{ steps.create-code-pr.outputs.PR_URL }} runs-on: ubuntu-latest + permissions: {} steps: - name: 'Generate GitHub App token' id: app-token @@ -251,6 +255,7 @@ jobs: with: app-id: ${{ secrets.SAP_AI_SDK_BOT_CLIENT_ID }} private-key: ${{ secrets.SAP_AI_SDK_BOT_PRIVATE_KEY }} + repositories: ai-sdk-java permission-contents: write permission-pull-requests: write @@ -301,6 +306,9 @@ jobs: app-id: ${{ secrets.SAP_AI_SDK_BOT_CLIENT_ID }} private-key: ${{ secrets.SAP_AI_SDK_BOT_PRIVATE_KEY }} owner: ${{ github.repository_owner }} + repositories: | + ai-sdk-java + ai-sdk permission-contents: write permission-pull-requests: write diff --git a/.github/workflows/spec-update.yaml b/.github/workflows/spec-update.yaml index 05254e88f..697d6c437 100644 --- a/.github/workflows/spec-update.yaml +++ b/.github/workflows/spec-update.yaml @@ -47,6 +47,8 @@ jobs: generate: name: 'Download, Generate, Compile and Push' runs-on: [ubuntu-latest] + permissions: + actions: read # for cache restore outputs: spec_diff: ${{ steps.spec_diff.outputs.spec_diff }} branch: ${{ steps.push.outputs.branch }} @@ -65,6 +67,7 @@ jobs: with: app-id: ${{ secrets.SAP_AI_SDK_BOT_CLIENT_ID }} private-key: ${{ secrets.SAP_AI_SDK_BOT_PRIVATE_KEY }} + repositories: ai-sdk-java permission-contents: write permission-pull-requests: write diff --git a/.github/workflows/weekly-spec-update.yaml b/.github/workflows/weekly-spec-update.yaml index c8b3a85f7..d7abc607f 100644 --- a/.github/workflows/weekly-spec-update.yaml +++ b/.github/workflows/weekly-spec-update.yaml @@ -10,6 +10,7 @@ jobs: runs-on: ubuntu-latest permissions: actions: write + contents: read strategy: matrix: From f033ee253c2b5869b80dfdc7abc02c6d75e418b7 Mon Sep 17 00:00:00 2001 From: Marika Marszalkowski Date: Thu, 2 Apr 2026 10:50:17 +0200 Subject: [PATCH 3/7] not needed --- .github/workflows/spec-update.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/spec-update.yaml b/.github/workflows/spec-update.yaml index 697d6c437..567162935 100644 --- a/.github/workflows/spec-update.yaml +++ b/.github/workflows/spec-update.yaml @@ -47,8 +47,7 @@ jobs: generate: name: 'Download, Generate, Compile and Push' runs-on: [ubuntu-latest] - permissions: - actions: read # for cache restore + permissions: {} outputs: spec_diff: ${{ steps.spec_diff.outputs.spec_diff }} branch: ${{ steps.push.outputs.branch }} From b5fd6b5ead4f73fafc867f28e974a5265a1cac91 Mon Sep 17 00:00:00 2001 From: Marika Marszalkowski Date: Thu, 2 Apr 2026 10:50:58 +0200 Subject: [PATCH 4/7] Apply suggestion from @marikaner --- .github/workflows/spec-update.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/spec-update.yaml b/.github/workflows/spec-update.yaml index 567162935..ffa0ff8e1 100644 --- a/.github/workflows/spec-update.yaml +++ b/.github/workflows/spec-update.yaml @@ -47,7 +47,6 @@ jobs: generate: name: 'Download, Generate, Compile and Push' runs-on: [ubuntu-latest] - permissions: {} outputs: spec_diff: ${{ steps.spec_diff.outputs.spec_diff }} branch: ${{ steps.push.outputs.branch }} From 9f9cc81559feabd747176349e67e2fd57f932894 Mon Sep 17 00:00:00 2001 From: Marika Marszalkowski Date: Thu, 2 Apr 2026 10:57:10 +0200 Subject: [PATCH 5/7] remove additional reads --- .github/workflows/spec-update-cleanup.yaml | 1 - .github/workflows/weekly-spec-update-cleanup.yaml | 2 -- .github/workflows/weekly-spec-update.yaml | 1 - 3 files changed, 4 deletions(-) diff --git a/.github/workflows/spec-update-cleanup.yaml b/.github/workflows/spec-update-cleanup.yaml index 5a9bc7cf8..2b7ee109d 100644 --- a/.github/workflows/spec-update-cleanup.yaml +++ b/.github/workflows/spec-update-cleanup.yaml @@ -34,7 +34,6 @@ on: jobs: cleanup: name: 'Delete Spec Update Branch' - needs: [auth] runs-on: [ubuntu-latest] permissions: contents: write diff --git a/.github/workflows/weekly-spec-update-cleanup.yaml b/.github/workflows/weekly-spec-update-cleanup.yaml index 419db3915..fa7f77172 100644 --- a/.github/workflows/weekly-spec-update-cleanup.yaml +++ b/.github/workflows/weekly-spec-update-cleanup.yaml @@ -9,8 +9,6 @@ jobs: find-stale-branches: name: 'Find stale spec-update branches' runs-on: ubuntu-latest - permissions: - contents: read outputs: branches: ${{ steps.list.outputs.branches }} steps: diff --git a/.github/workflows/weekly-spec-update.yaml b/.github/workflows/weekly-spec-update.yaml index d7abc607f..c8b3a85f7 100644 --- a/.github/workflows/weekly-spec-update.yaml +++ b/.github/workflows/weekly-spec-update.yaml @@ -10,7 +10,6 @@ jobs: runs-on: ubuntu-latest permissions: actions: write - contents: read strategy: matrix: From 3bdae8feb2c5d2635a9a5c3e1435b0006829e47f Mon Sep 17 00:00:00 2001 From: Marika Marszalkowski Date: Thu, 2 Apr 2026 10:57:54 +0200 Subject: [PATCH 6/7] Apply suggestion from @marikaner --- .github/workflows/perform-release.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/perform-release.yaml b/.github/workflows/perform-release.yaml index 8a0df93b0..40f74851e 100644 --- a/.github/workflows/perform-release.yaml +++ b/.github/workflows/perform-release.yaml @@ -25,9 +25,6 @@ jobs: release-notes-branch: ${{ steps.determine-branch-names.outputs.RELEASE_NOTES_BRANCH_NAME }} release-tag: ${{ steps.determine-branch-names.outputs.RELEASE_TAG }} release-commit: ${{ steps.determine-branch-names.outputs.RELEASE_COMMIT }} - permissions: - contents: read - pull-requests: read runs-on: ubuntu-latest steps: - name: 'Determine Branch Names' From c174000b04f26627f941c52263e117d28f40ceda Mon Sep 17 00:00:00 2001 From: Marika Marszalkowski Date: Thu, 2 Apr 2026 14:38:10 +0200 Subject: [PATCH 7/7] replace owner with plaintext --- .github/workflows/dependabot-automerge.yaml | 1 + .github/workflows/perform-release.yaml | 4 ++-- .github/workflows/prepare-release.yaml | 5 +++-- .github/workflows/spec-update.yaml | 1 + 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dependabot-automerge.yaml b/.github/workflows/dependabot-automerge.yaml index 36edb5956..2444d9d69 100644 --- a/.github/workflows/dependabot-automerge.yaml +++ b/.github/workflows/dependabot-automerge.yaml @@ -21,6 +21,7 @@ jobs: with: app-id: ${{ secrets.SAP_AI_SDK_BOT_CLIENT_ID }} private-key: ${{ secrets.SAP_AI_SDK_BOT_PRIVATE_KEY }} + owner: SAP repositories: ai-sdk-java permission-pull-requests: write diff --git a/.github/workflows/perform-release.yaml b/.github/workflows/perform-release.yaml index 40f74851e..e54071d08 100644 --- a/.github/workflows/perform-release.yaml +++ b/.github/workflows/perform-release.yaml @@ -52,7 +52,7 @@ jobs: with: app-id: ${{ secrets.SAP_AI_SDK_BOT_CLIENT_ID }} private-key: ${{ secrets.SAP_AI_SDK_BOT_PRIVATE_KEY }} - owner: ${{ github.repository_owner }} + owner: SAP repositories: ai-sdk permission-pull-requests: read @@ -102,7 +102,7 @@ jobs: with: app-id: ${{ secrets.SAP_AI_SDK_BOT_CLIENT_ID }} private-key: ${{ secrets.SAP_AI_SDK_BOT_PRIVATE_KEY }} - owner: ${{ github.repository_owner }} + owner: SAP repositories: | ai-sdk-java ai-sdk diff --git a/.github/workflows/prepare-release.yaml b/.github/workflows/prepare-release.yaml index ceb797b7a..10631592d 100644 --- a/.github/workflows/prepare-release.yaml +++ b/.github/workflows/prepare-release.yaml @@ -163,7 +163,7 @@ jobs: with: app-id: ${{ secrets.SAP_AI_SDK_BOT_CLIENT_ID }} private-key: ${{ secrets.SAP_AI_SDK_BOT_PRIVATE_KEY }} - owner: ${{ github.repository_owner }} + owner: SAP repositories: | ai-sdk-java ai-sdk @@ -255,6 +255,7 @@ jobs: with: app-id: ${{ secrets.SAP_AI_SDK_BOT_CLIENT_ID }} private-key: ${{ secrets.SAP_AI_SDK_BOT_PRIVATE_KEY }} + owner: SAP repositories: ai-sdk-java permission-contents: write permission-pull-requests: write @@ -305,7 +306,7 @@ jobs: with: app-id: ${{ secrets.SAP_AI_SDK_BOT_CLIENT_ID }} private-key: ${{ secrets.SAP_AI_SDK_BOT_PRIVATE_KEY }} - owner: ${{ github.repository_owner }} + owner: SAP repositories: | ai-sdk-java ai-sdk diff --git a/.github/workflows/spec-update.yaml b/.github/workflows/spec-update.yaml index ffa0ff8e1..334c6c370 100644 --- a/.github/workflows/spec-update.yaml +++ b/.github/workflows/spec-update.yaml @@ -65,6 +65,7 @@ jobs: with: app-id: ${{ secrets.SAP_AI_SDK_BOT_CLIENT_ID }} private-key: ${{ secrets.SAP_AI_SDK_BOT_PRIVATE_KEY }} + owner: SAP repositories: ai-sdk-java permission-contents: write permission-pull-requests: write