|
| 1 | +name: "Spec File Update Workflow" |
| 2 | + |
| 3 | +on: |
| 4 | + workflow_dispatch: |
| 5 | + inputs: |
| 6 | + file: |
| 7 | + description: "Which spec file to update" |
| 8 | + type: choice |
| 9 | + required: false |
| 10 | + options: |
| 11 | + - core |
| 12 | + - grounding |
| 13 | + - orchestration |
| 14 | + default: orchestration |
| 15 | + file-ref: |
| 16 | + description: "Branch or tag to checkout the spec file from" |
| 17 | + required: false |
| 18 | + default: main |
| 19 | + type: string |
| 20 | + create-pr: |
| 21 | + description: "Create a pull request after updating the spec file" |
| 22 | + required: false |
| 23 | + default: true |
| 24 | + type: boolean |
| 25 | + |
| 26 | +env: |
| 27 | + MVN_MULTI_THREADED_ARGS: --batch-mode --no-transfer-progress --fail-at-end --show-version --threads 1C |
| 28 | + JAVA_VERSION: 17 |
| 29 | + |
| 30 | +jobs: |
| 31 | + generate: |
| 32 | + name: "Download, Generate, Compile and Push" |
| 33 | + runs-on: [ubuntu-latest] |
| 34 | + permissions: |
| 35 | + pull-requests: write |
| 36 | + contents: write |
| 37 | + outputs: |
| 38 | + spec_diff: ${{ steps.spec_diff.outputs.spec_diff }} |
| 39 | + branch: ${{ steps.push.outputs.branch }} |
| 40 | + compilation_result: ${{ steps.compile.outputs.compilation_result }} |
| 41 | + test_result: ${{ steps.compile.outputs.test_result }} |
| 42 | + env: |
| 43 | + API_BASE_URL: "https://github.tools.sap/api/v3/repos" |
| 44 | + CHOICE: ${{ github.event.inputs.file }} |
| 45 | + REF: ${{ github.event.inputs.file-ref }} |
| 46 | + CREATE_PR: ${{ github.event.inputs.create-pr }} |
| 47 | + steps: |
| 48 | + - name: "Checkout repository" |
| 49 | + uses: actions/checkout@v4 |
| 50 | + with: |
| 51 | + token: ${{ secrets.BOT_SDK_JS_FOR_DOCS_REPO_PR }} |
| 52 | + |
| 53 | + - name: "Download specification file" |
| 54 | + id: download |
| 55 | + env: |
| 56 | + GH_ENTERPRISE_TOKEN: ${{ secrets.GH_TOOLS_TOKEN }} |
| 57 | + run: | |
| 58 | + case $CHOICE in |
| 59 | + core) |
| 60 | + API_URL="$API_BASE_URL/cloudsdk/cloud-sdk-java-tests/contents/aicore.yaml?ref=$REF" |
| 61 | + FILE_PATH='core/src/main/resources/spec/aicore.yaml' |
| 62 | + ;; |
| 63 | + grounding) |
| 64 | + # TODO |
| 65 | + exit 1 |
| 66 | + ;; |
| 67 | + orchestration) |
| 68 | + API_URL="$API_BASE_URL/AI/llm-orchestration/contents/src/spec/api.yaml?ref=$REF" |
| 69 | + FILE_PATH='orchestration/src/main/resources/spec/orchestration.yaml' |
| 70 | + ;; |
| 71 | + esac |
| 72 | + |
| 73 | + echo "Downloading $CHOICE specification file from $API_URL ..." |
| 74 | + |
| 75 | + gh api $API_URL -H "Accept: application/vnd.github.raw" > $FILE_PATH |
| 76 | +
|
| 77 | + - name: "Exit if there are no changes" |
| 78 | + id: spec_diff |
| 79 | + run: | |
| 80 | + if [[ `git status --porcelain` ]]; then |
| 81 | + echo "spec_diff=true" >> "$GITHUB_OUTPUT" |
| 82 | + else |
| 83 | + echo "spec_diff=false" >> "$GITHUB_OUTPUT" |
| 84 | + fi |
| 85 | +
|
| 86 | + - name: "Checkout or Create Branch" |
| 87 | + # Always create a new branch to ensure we generate from a clean state. |
| 88 | + # In case a PR exist we can't delete and re-create the branch (without closing the PR first). |
| 89 | + # So the workflow will exist in this case. |
| 90 | + id: branch |
| 91 | + env: |
| 92 | + GH_TOKEN: ${{ secrets.BOT_SDK_JS_FOR_DOCS_REPO_PR }} |
| 93 | + run: | |
| 94 | + BRANCH="spec-update/$CHOICE/$REF" |
| 95 | + if gh pr list --head $BRANCH --json number -q '.[].number' | grep -q .; then |
| 96 | + echo "An open PR already exists for this branch. Please close the PR first before re-running the workflow." |
| 97 | + exit 1 |
| 98 | + fi |
| 99 | +
|
| 100 | + if git ls-remote --exit-code origin refs/heads/$BRANCH >/dev/null 2>&1; then |
| 101 | + echo "Branch '$BRANCH' exists on remote, deleting it..." |
| 102 | + git push origin --delete $BRANCH |
| 103 | + fi |
| 104 | + git checkout -b $BRANCH |
| 105 | + echo "branch=$BRANCH" >> "$GITHUB_OUTPUT" |
| 106 | +
|
| 107 | + - name: "Setup java" |
| 108 | + uses: actions/setup-java@v4 |
| 109 | + if: steps.spec_diff.outputs.spec_diff == 'true' |
| 110 | + with: |
| 111 | + distribution: "temurin" |
| 112 | + java-version: ${{ env.JAVA_VERSION }} |
| 113 | + cache: 'maven' |
| 114 | + |
| 115 | + - name: "Generate" |
| 116 | + id: generate |
| 117 | + if: steps.spec_diff.outputs.spec_diff == 'true' |
| 118 | + run: | |
| 119 | + mvn process-sources -Dgenerate ${{ env.MVN_MULTI_THREADED_ARGS }} |
| 120 | +
|
| 121 | + - name: "Compile and Test" |
| 122 | + id: compile |
| 123 | + if: steps.spec_diff.outputs.spec_diff == 'true' |
| 124 | + # Compilation can easily fail e.g. from re-namings and has to be fixed manually. |
| 125 | + # Thus, this action raises the PR anyway and only reports success or failure of compilation and testing. |
| 126 | + run: | |
| 127 | + if mvn test-compile ${{ env.MVN_MULTI_THREADED_ARGS }} ; then |
| 128 | + echo "compilation_result=success" >> "$GITHUB_OUTPUT" |
| 129 | + if mvn test ${{ env.MVN_MULTI_THREADED_ARGS }} ; then |
| 130 | + echo "test_result=success" >> "$GITHUB_OUTPUT" |
| 131 | + else |
| 132 | + echo "test_result=failure" >> "$GITHUB_OUTPUT" |
| 133 | + fi |
| 134 | + else |
| 135 | + echo "compilation_result=failure" >> "$GITHUB_OUTPUT" |
| 136 | + fi |
| 137 | +
|
| 138 | + - name: "Push changes" |
| 139 | + id: push |
| 140 | + if: steps.spec_diff.outputs.spec_diff == 'true' |
| 141 | + run: | |
| 142 | + git config --global user.email "[email protected]" |
| 143 | + git config --global user.name "SAP Cloud SDK Bot" |
| 144 | + git add . |
| 145 | + git commit -m "Update $CHOICE based on $REF" |
| 146 | + git push --set-upstream origin ${{ steps.branch.outputs.branch }} |
| 147 | +
|
| 148 | + - name: "Create PR" |
| 149 | + if: ${{ env.CREATE_PR && steps.spec_diff.outputs.spec_diff == 'true'}} |
| 150 | + env: |
| 151 | + GH_TOKEN: ${{ secrets.BOT_SDK_JS_FOR_DOCS_REPO_PR }} |
| 152 | + run: | |
| 153 | + gh pr create --base main --head ${{ steps.branch.outputs.branch }} --title "feat: [DevOps] Update $CHOICE Specification" --body " |
| 154 | + ## Context |
| 155 | + |
| 156 | + Update $CHOICE specification file based on $REF. |
| 157 | + |
| 158 | + This PR was created automatically by the [spec-update workflow](https://github.com/SAP/ai-sdk-java/actions/workflows/spec-update.yaml). |
| 159 | + You can commit on top of this branch, but as long as this PR is open the action can't be re-run. |
| 160 | + |
| 161 | + - Compilation outcome: ${{ steps.compile.output.test_result }} |
| 162 | + - Test run outcome: ${{ steps.compile.output.test_result }} |
| 163 | + |
| 164 | + Before merging, make sure to update tests and release notes, if necessary. |
| 165 | + |
| 166 | + ## Definition of Done |
| 167 | +
|
| 168 | + - [ ] Unit tests cover new classes |
| 169 | + - [ ] Release notes updated |
| 170 | + " |
| 171 | +
|
| 172 | + - name: "Print Summary" |
| 173 | + if: ${{ always() }} |
| 174 | + run: | |
| 175 | + echo "Branch creation: ${{ steps.branch.outcome }}" |
| 176 | + echo "File download outcome: ${{ steps.download.outcome }}" |
| 177 | + echo "Spec file contained changes: ${{ steps.spec_diff.outputs.spec_diff }}" |
| 178 | + echo "Client generation outcome: ${{ steps.generate.outcome }}" |
| 179 | + echo "Client compilation outcome: ${{ steps.compile.output.compilation_result }}" |
| 180 | + echo "Client test outcome: ${{ steps.compile.output.test_result }}" |
0 commit comments