From 05761738affd25be116998f1d3e8011d4b797ae2 Mon Sep 17 00:00:00 2001 From: Matthias Kuhr Date: Mon, 20 Jan 2025 18:10:30 +0100 Subject: [PATCH 1/2] chore: Add Spec Update Automation --- .github/workflows/spec-update.yaml | 168 +++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 .github/workflows/spec-update.yaml diff --git a/.github/workflows/spec-update.yaml b/.github/workflows/spec-update.yaml new file mode 100644 index 000000000..ba37f9872 --- /dev/null +++ b/.github/workflows/spec-update.yaml @@ -0,0 +1,168 @@ +name: "Spec File Update Workflow" + +on: + workflow_dispatch: + inputs: + file: + description: "Which spec file to update" + type: choice + required: false + options: + - core + - grounding + - orchestration + default: orchestration + file-ref: + description: "Branch or tag to checkout the spec file from" + required: false + default: main + type: string + create-pr: + description: "Create a pull request after updating the spec file" + required: false + default: true + type: boolean + +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 }} + compilation_result: ${{ steps.compile.outputs.compilation_result }} + test_result: ${{ steps.compile.outputs.test_result }} + env: + API_BASE_URL: "https://github.tools.sap/api/v3/repos" + CHOICE: ${{ github.event.inputs.file }} + REF: ${{ github.event.inputs.file-ref }} + CREATE_PR: ${{ github.event.inputs.create-pr }} + steps: + - name: "Checkout repository" + uses: actions/checkout@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + - name: "Checkout or Create Branch" + id: branch + # Checkout branch if it exists, otherwise create it + run: | + BRANCH="spec-update/$CHOICE/$REF" + git fetch origin $BRANCH || true + git checkout -B $BRANCH origin/$BRANCH || git checkout -b $BRANCH + echo "branch=$BRANCH" >> "$GITHUB_OUTPUT" + + - name: "Download specification file" + id: download + env: + GH_ENTERPRISE_TOKEN: ${{ secrets.GH_TOOLS_TOKEN }} + run: | + case $CHOICE in + core) + API_URL="$API_BASE_URL/cloudsdk/cloud-sdk-java-tests/contents/aicore.yaml?ref=$REF" + FILE_PATH='packages/ai-api/src/spec/AI_CORE_API.yaml' + ;; + grounding) + # TODO + exit 1 + ;; + orchestration) + API_URL="$API_BASE_URL/AI/llm-orchestration/contents/src/spec/api.yaml?ref=$REF" + FILE_PATH='packages/orchestration/src/spec/api.yaml' + ;; + esac + + echo "Downloading $CHOICE specification file from $API_URL ..." + + gh api $API_URL -H "Accept: application/vnd.github.raw" > $FILE_PATH + + - name: "Exit if there are no changes" + id: spec_diff + run: | + if [[ `git status --porcelain` ]]; then + echo "spec_diff=true" >> "$GITHUB_OUTPUT" + else + echo "spec_diff=false" >> "$GITHUB_OUTPUT" + fi + + - uses: sap/ai-sdk-js/.github/actions/setup@main + if: steps.spec_diff.outputs.spec_diff == 'true' + with: + node-version: 20 + + - name: "Generate" + id: generate + if: steps.spec_diff.outputs.spec_diff == 'true' + run: | + pnpm generate + + - name: "Compile and Test" + id: compile + if: steps.spec_diff.outputs.spec_diff == 'true' + # Compilation can easily fail e.g. from re-namings and has to be fixed manually. + # Thus, this action raises the PR anyway and only reports success or failure of compilation and testing. + run: | + if pnpm compile ; then + echo "compilation_result=success" >> "$GITHUB_OUTPUT" + if pnpm test ; then + echo "test_result=success" >> "$GITHUB_OUTPUT" + else + echo "test_result=failure" >> "$GITHUB_OUTPUT" + fi + else + echo "compilation_result=failure" >> "$GITHUB_OUTPUT" + echo "test_result=skipped" >> "$GITHUB_OUTPUT" + fi + + - name: "Push changes" + id: push + if: steps.spec_diff.outputs.spec_diff == 'true' + run: | + git config --global user.email "cloudsdk@sap.com" + git config --global user.name "SAP Cloud SDK Bot" + git add . + git commit -m "Update $CHOICE based on $REF" + git push --set-upstream origin ${{ steps.branch.outputs.branch }} + + - name: "Create PR" + if: ${{ env.CREATE_PR == 'true' && steps.spec_diff.outputs.spec_diff == 'true'}} + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + BRANCH: ${{ steps.branch.outputs.branch }} + run: | + if gh pr list --head $BRANCH --json number -q '.[].number' | grep -q .; then + echo "An open PR already exists for this branch. Skipping PR creation." + exit 0 + fi + + gh pr create --base main --head $BRANCH --title "feat: [DevOps] Update $CHOICE Specification" --body " + ## Context + + Update $CHOICE specification file based on $REF. + + This PR was created automatically by the [spec-update workflow](https://github.com/SAP/ai-sdk-js/actions/workflows/spec-update.yaml). + You can commit on top of this branch, but as long as this PR is open the action can't be re-run. + + - Compilation outcome: ${{ steps.compile.output.compilation_result }} + - Test run outcome: ${{ steps.compile.output.test_result }} + + Before merging, make sure to update tests and release notes, if necessary. + + ## Definition of Done + + - [ ] Unit tests cover new classes + - [ ] Release notes updated + " + + - name: "Print Summary" + if: ${{ always() }} + run: | + echo "File download outcome: ${{ steps.download.outcome }}" + echo "Spec file contained changes: ${{ steps.spec_diff.outputs.spec_diff }}" + echo "Client generation outcome: ${{ steps.generate.outcome }}" + echo "Client compilation outcome: ${{ steps.compile.output.compilation_result }}" + echo "Client test outcome: ${{ steps.compile.output.test_result }}" + echo "Branch creation: ${{ steps.push.outcome }}" From 828be931784f5d5bd0ddbdbf230b6023015fa1d5 Mon Sep 17 00:00:00 2001 From: Matthias Kuhr Date: Wed, 22 Jan 2025 13:03:26 +0100 Subject: [PATCH 2/2] Fix pnpm commands --- .github/workflows/spec-update.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/spec-update.yaml b/.github/workflows/spec-update.yaml index ba37f9872..f17f9b472 100644 --- a/.github/workflows/spec-update.yaml +++ b/.github/workflows/spec-update.yaml @@ -97,6 +97,7 @@ jobs: id: generate if: steps.spec_diff.outputs.spec_diff == 'true' run: | + pnpm install pnpm generate - name: "Compile and Test" @@ -107,7 +108,7 @@ jobs: run: | if pnpm compile ; then echo "compilation_result=success" >> "$GITHUB_OUTPUT" - if pnpm test ; then + if pnpm test:unit && pnpm test:type ; then echo "test_result=success" >> "$GITHUB_OUTPUT" else echo "test_result=failure" >> "$GITHUB_OUTPUT" @@ -153,7 +154,7 @@ jobs: ## Definition of Done - - [ ] Unit tests cover new classes + - [ ] Unit / type tests cover new classes - [ ] Release notes updated "