|
| 1 | +# Keep the cldk python-sdk (codellm-devkit/python-sdk) in lockstep with this repo: |
| 2 | +# on every codeanalyzer-java release, record the new backend version in the SDK and |
| 3 | +# cut a matching SDK release. |
| 4 | +# |
| 5 | +# What it does, against the SDK's default branch: |
| 6 | +# 1. set [tool.backend-versions].codeanalyzer-java to the released version |
| 7 | +# 2. patch-bump the SDK's own [project].version (e.g. 1.1.3 -> 1.1.4) |
| 8 | +# 3. commit both and push a v<sdk-version> tag |
| 9 | +# -> the SDK's own release.yml (trigger: push tag v*.*.*) runs its tests, |
| 10 | +# bundles the latest codeanalyzer jar, and publishes to PyPI. That workflow |
| 11 | +# deletes the tag if its tests fail, so a broken bump never ships. |
| 12 | +# |
| 13 | +# Deliberately NOT touched: [project.dependencies] "codeanalyzer-java==X". That pin |
| 14 | +# resolves from real PyPI (which lags — only 2.3.7 is published there), whereas |
| 15 | +# releases are distributed as GitHub release assets + a Pages index. The SDK build |
| 16 | +# bundles the jar directly (its release.yml injects releases/latest), so |
| 17 | +# [tool.backend-versions] is the field that tracks the backend, and bumping the hard |
| 18 | +# dependency pin to a not-on-PyPI version would break `uv sync --frozen`. |
| 19 | +# |
| 20 | +# Requirements: |
| 21 | +# secrets.CLDK_AUTH_TOKEN - org PAT with contents:write on codellm-devkit/python-sdk. |
| 22 | +# Used to push the commit + tag; pushing the tag with a PAT (not GITHUB_TOKEN) is |
| 23 | +# what triggers the SDK's release workflow. The SDK's own GITHUB_TOKEN / PYPI_API_TOKEN |
| 24 | +# handle the publish on its side. |
| 25 | +name: sdk-lockstep |
| 26 | + |
| 27 | +on: |
| 28 | + release: |
| 29 | + types: [published] |
| 30 | + workflow_dispatch: |
| 31 | + inputs: |
| 32 | + tag: |
| 33 | + description: "codeanalyzer-java release tag to propagate, e.g. v2.4.1" |
| 34 | + required: true |
| 35 | + |
| 36 | +env: |
| 37 | + SDK_REPO: codellm-devkit/python-sdk |
| 38 | + TAG: ${{ github.event.release.tag_name || inputs.tag }} |
| 39 | + |
| 40 | +jobs: |
| 41 | + lockstep: |
| 42 | + runs-on: ubuntu-latest |
| 43 | + steps: |
| 44 | + - name: Resolve backend version |
| 45 | + run: | |
| 46 | + test -n "${TAG}" || { echo "::error::no release tag resolved"; exit 1; } |
| 47 | + echo "BACKEND_VERSION=${TAG#v}" >> "$GITHUB_ENV" |
| 48 | +
|
| 49 | + - name: Check out the SDK repo |
| 50 | + uses: actions/checkout@v5 |
| 51 | + with: |
| 52 | + repository: ${{ env.SDK_REPO }} |
| 53 | + token: ${{ secrets.CLDK_AUTH_TOKEN }} |
| 54 | + ref: main |
| 55 | + fetch-depth: 0 |
| 56 | + |
| 57 | + - name: Bump backend pin + SDK version |
| 58 | + id: bump |
| 59 | + run: | |
| 60 | + python -m pip install --quiet tomlkit |
| 61 | + python - "$BACKEND_VERSION" <<'PY' |
| 62 | + import os, sys, tomlkit |
| 63 | +
|
| 64 | + backend = sys.argv[1] |
| 65 | + path = "pyproject.toml" |
| 66 | + doc = tomlkit.parse(open(path).read()) |
| 67 | + out = open(os.environ["GITHUB_OUTPUT"], "a") |
| 68 | +
|
| 69 | + bv = doc["tool"]["backend-versions"] |
| 70 | + if str(bv.get("codeanalyzer-java")) == backend: |
| 71 | + out.write("skip=true\n") |
| 72 | + print(f"SDK already records codeanalyzer-java {backend}; nothing to do.") |
| 73 | + raise SystemExit(0) |
| 74 | +
|
| 75 | + # patch-bump the SDK's own version (X.Y.Z -> X.Y.(Z+1)) |
| 76 | + cur = str(doc["project"]["version"]) |
| 77 | + parts = cur.split(".") |
| 78 | + if len(parts) != 3 or not parts[-1].isdigit(): |
| 79 | + raise SystemExit(f"unexpected SDK version {cur!r}; expected numeric X.Y.Z") |
| 80 | + parts[-1] = str(int(parts[-1]) + 1) |
| 81 | + new = ".".join(parts) |
| 82 | +
|
| 83 | + bv["codeanalyzer-java"] = backend |
| 84 | + doc["project"]["version"] = new |
| 85 | + open(path, "w").write(tomlkit.dumps(doc)) |
| 86 | +
|
| 87 | + out.write("skip=false\n") |
| 88 | + out.write(f"sdk_version={new}\n") |
| 89 | + print(f"codeanalyzer-java backend -> {backend}; SDK {cur} -> {new}") |
| 90 | + PY |
| 91 | +
|
| 92 | + - name: Commit, tag, and push to the SDK |
| 93 | + if: steps.bump.outputs.skip == 'false' |
| 94 | + env: |
| 95 | + BACKEND_VERSION: ${{ env.BACKEND_VERSION }} |
| 96 | + SDK_VERSION: ${{ steps.bump.outputs.sdk_version }} |
| 97 | + run: | |
| 98 | + NEW_TAG="v${SDK_VERSION}" |
| 99 | + if git ls-remote --exit-code --tags origin "refs/tags/${NEW_TAG}" >/dev/null 2>&1; then |
| 100 | + echo "::notice::tag ${NEW_TAG} already exists in the SDK; skipping." |
| 101 | + exit 0 |
| 102 | + fi |
| 103 | + git config user.name "cldk-bot" |
| 104 | + git config user.email "cldk-bot@users.noreply.github.com" |
| 105 | + git add pyproject.toml |
| 106 | + git commit -m "chore: bump codeanalyzer-java backend to ${BACKEND_VERSION} (SDK ${SDK_VERSION})" |
| 107 | + git tag -a "${NEW_TAG}" -m "cldk ${SDK_VERSION} (codeanalyzer-java ${BACKEND_VERSION})" |
| 108 | + git push origin HEAD:refs/heads/main |
| 109 | + git push origin "refs/tags/${NEW_TAG}" |
| 110 | + echo "::notice::pushed SDK ${NEW_TAG} (codeanalyzer-java ${BACKEND_VERSION}) -> triggers the SDK release." |
0 commit comments