Skip to content

Commit 0c3a066

Browse files
feat: update bindings to v2.0.29 (API v1.1285.0) and automate future updates (#96)
Binding version: 2.0.29 CloudSmith API version: 1.1285.0 Bindings: - Regenerate Python, Ruby, and Java bindings against API v1.1285.0 Tooling and automation: - Automate the Ruby apostrophe escaping (swagger-codegen emits an unescaped single-quoted enum value) in scripts/fix-ruby-escaping.sh using ruby, invoked from bindings/ruby/build.sh so a single build always emits valid Ruby - Make linting a mandatory build step: scripts/build.sh runs `ruff check --fix`, which fails only on genuinely unfixable violations - Harden update-bindings.sh: run pre-commit to convergence and refuse to push when a hook aborts the commit - Manage the host toolchain with mise via a top-level .mise.toml (ruby, python, uv, jq) shared by local dev and CI - Add the "Update API bindings" GitHub Actions workflow: regenerate and open a PR on demand or daily, only when the bindings actually change, closing any superseded automated PRs first - Move linting and security scanning to GitHub Actions (mirroring cloudsmith-cli): a Lint workflow runs ruff via mise, and a Security workflow runs zizmor via zizmorcore/zizmor-action; the CircleCI pre-commit job is removed, leaving CircleCI to only test and deploy the bindings - Harden the workflows against zizmor's findings: pass workflow_dispatch inputs and step outputs through env instead of interpolating them into run blocks, set persist-credentials: false, and hash-pin all actions to the latest release - chmod 755 the source shell scripts - Document the mise + Docker workflow in README.md and CONTRIBUTING.md Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 52a50dc commit 0c3a066

289 files changed

Lines changed: 1700 additions & 402 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.circleci/config.yml

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -58,27 +58,11 @@ jobs:
5858
- prepare_deploy_environment
5959
- deploy_bindings:
6060
language: <<parameters.language>>
61-
pre_commit:
62-
description: "Run pre-commit hooks"
63-
docker:
64-
- image: cimg/python:3.8
65-
steps:
66-
- checkout
67-
- run:
68-
name: "Install dependencies"
69-
command: |
70-
python3 -m pip install --upgrade pip
71-
pip install pre-commit
72-
- run:
73-
name: "Run pre-commit"
74-
command: pre-commit run --all-files
75-
7661

7762
workflows:
7863
version: 2
7964
test_and_deploy:
8065
jobs:
81-
- pre_commit
8266
- test:
8367
name: "Test Java"
8468
language: java

.github/workflows/lint.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: Lint
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
pull_request:
8+
branches:
9+
- "**"
10+
11+
permissions:
12+
contents: read
13+
14+
jobs:
15+
ruff:
16+
name: Check Python style (ruff)
17+
runs-on: ubuntu-latest
18+
steps:
19+
- name: Checkout
20+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
21+
with:
22+
persist-credentials: false
23+
24+
- name: Set up mise
25+
uses: jdx/mise-action@e6a8b3978addb5a52f2b4cd9d91eafa7f0ab959d # v4.2.0
26+
with:
27+
install: false
28+
29+
- name: Install tools with mise
30+
run: mise install python uv
31+
32+
- name: Run ruff
33+
run: mise exec python uv -- uvx prek run ruff --all-files
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
name: Update API bindings
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
version:
7+
description: "Binding version (leave blank to auto-increment the patch version)"
8+
required: false
9+
type: string
10+
schedule:
11+
# Daily at 06:00 UTC
12+
- cron: "0 6 * * *"
13+
14+
permissions:
15+
contents: write
16+
pull-requests: write
17+
18+
jobs:
19+
update-bindings:
20+
runs-on: ubuntu-latest
21+
steps:
22+
- name: Checkout
23+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
24+
with:
25+
persist-credentials: false
26+
27+
- name: Set up tools
28+
uses: jdx/mise-action@e6a8b3978addb5a52f2b4cd9d91eafa7f0ab959d # v4.2.0
29+
30+
- name: Generate bindings
31+
run: mise run build
32+
33+
- name: Detect changes
34+
id: detect
35+
env:
36+
INPUT_VERSION: ${{ inputs.version }}
37+
run: |
38+
if [ -n "$INPUT_VERSION" ] || [ -n "$(git status --porcelain)" ]; then
39+
echo "changed=true" >> "$GITHUB_OUTPUT"
40+
else
41+
echo "changed=false" >> "$GITHUB_OUTPUT"
42+
echo "Bindings already match the current API; no PR needed."
43+
fi
44+
45+
- name: Bump version and regenerate
46+
if: steps.detect.outputs.changed == 'true'
47+
id: versions
48+
env:
49+
INPUT_VERSION: ${{ inputs.version }}
50+
run: |
51+
api_version=$(curl -s --max-time 30 "https://api.cloudsmith.io/status/check/basic/" | jq -r '.version')
52+
if [ -z "$api_version" ] || [ "$api_version" = "null" ]; then
53+
echo "Could not fetch CloudSmith API version" >&2
54+
exit 1
55+
fi
56+
57+
current_version=$(grep -E '^package_version=' scripts/common.sh | cut -d'"' -f2)
58+
if [ -n "$INPUT_VERSION" ]; then
59+
new_version="$INPUT_VERSION"
60+
else
61+
IFS='.' read -r major minor patch <<< "$current_version"
62+
new_version="${major}.${minor}.$((patch + 1))"
63+
fi
64+
65+
sed -i -E "s/^package_version=.*/package_version=\"${new_version}\"/" scripts/common.sh
66+
mise run build
67+
68+
echo "api_version=$api_version" >> "$GITHUB_OUTPUT"
69+
echo "new_version=$new_version" >> "$GITHUB_OUTPUT"
70+
71+
- name: Close stale automated binding PRs
72+
if: steps.detect.outputs.changed == 'true'
73+
env:
74+
GH_TOKEN: ${{ github.token }}
75+
NEW_VERSION: ${{ steps.versions.outputs.new_version }}
76+
run: |
77+
keep="automated/update-bindings-v${NEW_VERSION}"
78+
gh pr list --state open --json number,headRefName \
79+
--jq '.[]
80+
| select(.headRefName | startswith("automated/update-bindings-"))
81+
| select(.headRefName != "'"$keep"'")
82+
| .number' \
83+
| while read -r number; do
84+
[ -n "$number" ] || continue
85+
gh pr close "$number" --delete-branch \
86+
--comment "Superseded by automated bindings update v${NEW_VERSION}."
87+
done
88+
89+
- name: Create pull request
90+
if: steps.detect.outputs.changed == 'true'
91+
uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1
92+
with:
93+
branch: automated/update-bindings-v${{ steps.versions.outputs.new_version }}
94+
base: master
95+
title: "feat: update bindings to v${{ steps.versions.outputs.new_version }} (API v${{ steps.versions.outputs.api_version }})"
96+
commit-message: "feat: update bindings to v${{ steps.versions.outputs.new_version }} (API v${{ steps.versions.outputs.api_version }})"
97+
body: |
98+
Automated API bindings update.
99+
100+
- Binding version: `${{ steps.versions.outputs.new_version }}`
101+
- CloudSmith API version: `${{ steps.versions.outputs.api_version }}`
102+
103+
Generated by the **Update API bindings** workflow.
104+
labels: |
105+
bindings
106+
automated
107+
delete-branch: true

.github/workflows/zizmor.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: Security
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
paths:
8+
- ".github/workflows/**"
9+
pull_request:
10+
branches:
11+
- "**"
12+
paths:
13+
- ".github/workflows/**"
14+
15+
permissions: {}
16+
17+
jobs:
18+
zizmor:
19+
name: Scan GitHub Actions workflows
20+
runs-on: ubuntu-latest
21+
permissions:
22+
security-events: write
23+
contents: read
24+
actions: read
25+
steps:
26+
- name: Checkout repository
27+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
28+
with:
29+
persist-credentials: false
30+
31+
- name: Run zizmor
32+
uses: zizmorcore/zizmor-action@192e21d79ab29983730a13d1382995c2307fbcaa # v0.5.7

.mise.toml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Host toolchain for working with this repo. Note: binding generation runs
2+
# inside the pinned swaggerapi/swagger-codegen-cli Docker image (see
3+
# scripts/common.sh), so Docker remains a separate prerequisite that mise does
4+
# not manage. The CircleCI test matrix pins its own runtimes via cimg images.
5+
6+
[tools]
7+
ruby = "3.4"
8+
python = "3.12"
9+
uv = "latest"
10+
jq = "latest"
11+
12+
[tasks.build]
13+
description = "Generate all API bindings and apply ruff autofixes (requires Docker)"
14+
run = "./scripts/build.sh"
15+
16+
[tasks.update-bindings]
17+
description = "Bump the version, regenerate bindings, and open a PR"
18+
run = "./scripts/update-bindings.sh"

.pre-commit-config.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,7 @@ repos:
44
hooks:
55
- id: ruff
66
args: [ --fix ]
7+
- repo: https://github.com/zizmorcore/zizmor-pre-commit
8+
rev: v1.27.0
9+
hooks:
10+
- id: zizmor

CONTRIBUTING.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,25 @@ Please refer to Cloudsmith's standard guide on [Open-Source Contributing](https:
44

55
## Updating bindings
66

7+
The host toolchain is managed with [mise](https://mise.jdx.dev/) via the top-level `.mise.toml`, so local and CI environments use the same tools. Run `mise install` once to get them. You also need [Docker](https://www.docker.com/) running, as generation happens inside the pinned `swagger-codegen-cli` image (see `scripts/common.sh`). Linting (`ruff`) runs automatically as part of the build.
8+
79
### Manual approach
810

911
* Update `package_version` in `scripts/common.sh`
10-
* Run `./scripts/build.sh` to generate bindings
11-
* Create a PR specifing API and binding version
12+
* Run `mise run build` to generate the bindings (ruff autofixes are applied as part of the build)
13+
* Create a PR specifying the API and binding version
1214

1315
### Automated approach
1416

15-
* Run `./scripts/update-bindings.sh` to automatically update the bindings.
17+
* Run `mise run update-bindings` to automatically update the bindings.
1618
* This will then provide you with the URL for the PR to release the updated bindings.
17-
* Preferred usage: `./scripts/update-bindings.sh`
1819
* For full options and usage examples, run: `./scripts/update-bindings.sh --help`
1920

21+
### Scheduled / on-demand automation
22+
23+
* The `Update API bindings` GitHub Actions workflow regenerates the bindings and opens a PR — daily on a schedule, or on demand via **Run workflow** (optionally with a specific version).
24+
* It only opens a PR when the regenerated bindings actually change.
25+
2026
## Contributor License Agreement
2127

2228
By making any contributions to Cloudsmith Ltd projects you agree to be bound by the terms of the Cloudsmith Ltd [Contributor License Agreement](https://docs.cloudsmith.com/contributor-license-agreement).

README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,27 @@ To receive configuration help (in order to setup `build.sh` correctly), execute:
4040
Where `<language>` is the language you're generating bindings for (e.g. `python`).
4141

4242

43+
## Local Development
44+
45+
The host toolchain is managed with [mise](https://mise.jdx.dev/) via the top-level `.mise.toml`, so local development and CI use the same tools. With mise installed:
46+
47+
```sh
48+
mise install # installs the pinned host tools (ruby, uv, jq)
49+
```
50+
51+
You also need [Docker](https://www.docker.com/) running — binding generation happens inside the pinned `swagger-codegen-cli` image (see `scripts/common.sh`), which mise does not manage.
52+
53+
Common tasks:
54+
55+
```sh
56+
mise run build # regenerate all bindings; ruff autofixes are applied as part of the build
57+
mise run update-bindings # bump the version, regenerate the bindings, and open a pull request
58+
```
59+
60+
Linting is a mandatory step of `build`: `ruff` fixes issues in place and fails the build only if it finds something it cannot fix, so a successful `mise run build` always produces lint-clean bindings.
61+
62+
Binding updates also run automatically through the `Update API bindings` GitHub Actions workflow — daily on a schedule, or on demand via **Run workflow** (optionally with a specific version). It opens a pull request only when the regenerated bindings actually change.
63+
4364
## Versioning
4465

4566
The version of the generated library bindings is automatically made to match the upstream API. So if the Cloudsmith API is currently `0.22.2`, then the language bindings will also be `0.22.2`.

bindings/java/src/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ Add this dependency to your project's POM:
4040
<dependency>
4141
<groupId>io.cloudsmith.api</groupId>
4242
<artifactId>cloudsmith-api</artifactId>
43-
<version>2.0.27</version>
43+
<version>2.0.29</version>
4444
<scope>compile</scope>
4545
</dependency>
4646
```
@@ -50,7 +50,7 @@ Add this dependency to your project's POM:
5050
Add this dependency to your project's build file:
5151

5252
```groovy
53-
compile "io.cloudsmith.api:cloudsmith-api:2.0.27"
53+
compile "io.cloudsmith.api:cloudsmith-api:2.0.29"
5454
```
5555

5656
### Others
@@ -63,7 +63,7 @@ mvn clean package
6363

6464
Then manually install the following JARs:
6565

66-
* `target/cloudsmith-api-2.0.27.jar`
66+
* `target/cloudsmith-api-2.0.29.jar`
6767
* `target/lib/*.jar`
6868

6969
## Getting Started

bindings/java/src/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ apply plugin: 'idea'
22
apply plugin: 'eclipse'
33

44
group = 'io.cloudsmith.api'
5-
version = '2.0.27'
5+
version = '2.0.29'
66

77
buildscript {
88
repositories {

0 commit comments

Comments
 (0)