From 8c75a89a7d5c0b94d0455f19fe0626ea7e589e83 Mon Sep 17 00:00:00 2001 From: bzp2010 Date: Mon, 26 Oct 2026 13:58:16 +0800 Subject: [PATCH 1/3] ci(release): make the Rust build the primary release Publish the Rust CLI under the plain adc names and move the JavaScript CLI to an adc_js prefix. - Release archives: Rust is adc___, JavaScript is adc_js___. The install script keeps working because it already downloads the plain name. - Docker images: api7/adc: and dev are built from the Rust Dockerfile, the JavaScript image is published as -js and dev-js from Dockerfile.js. - Linux binaries are built in an AlmaLinux 8 container and a step fails the release if they require a glibc symbol newer than 2.28. A smoke job runs them in Debian and Ubuntu containers on both architectures. - The Linux job fails when the tag does not match the version in rust/Cargo.toml. - Add docs for the release workflows and the Docker and install assets. --- .dockerignore | 1 + .github/workflows/README.md | 28 ++++++ .github/workflows/docker.yaml | 28 ++++++ .github/workflows/release.yaml | 129 +++++++++++++++++++--------- README.md | 2 + libs/tools/README.md | 23 +++++ libs/tools/src/docker/Dockerfile | 19 ++-- libs/tools/src/docker/Dockerfile.js | 20 +++++ 8 files changed, 196 insertions(+), 54 deletions(-) create mode 100644 .github/workflows/README.md create mode 100644 libs/tools/README.md create mode 100644 libs/tools/src/docker/Dockerfile.js diff --git a/.dockerignore b/.dockerignore index 4f75c951..43a0d0c5 100644 --- a/.dockerignore +++ b/.dockerignore @@ -3,3 +3,4 @@ node_modules .gitignore *.md dist +rust/target diff --git a/.github/workflows/README.md b/.github/workflows/README.md new file mode 100644 index 00000000..129e2a6c --- /dev/null +++ b/.github/workflows/README.md @@ -0,0 +1,28 @@ +# Workflows + +Only the release related workflows are described here. + +## Release artifacts + +`release.yaml` runs on `v*.*.*` tags and uploads archives to the GitHub release. The Rust CLI is the primary implementation and the JavaScript CLI is published under an `adc_js_` prefix. + +| Implementation | Archive name | Binary inside | +|---|---|---| +| Rust | `adc___.{tar.gz,zip}` | `adc` | +| Rust debug info | `adc____debuginfo.{tar.gz,zip}` | `adc.debug` (Linux), `adc.dSYM` (macOS), `adc.pdb` (Windows) | +| JavaScript | `adc_js___.{tar.gz,zip}` | `adc` | + +- `` is `linux`, `darwin` or `windows`, `` is `amd64` or `arm64`. +- The version comes from the tag. The Linux job fails the release when the tag does not match `version` under `[workspace.package]` in `rust/Cargo.toml`, so bump that first. +- Pull requests with the `test/build` label build only the Rust archives and upload them as workflow artifacts. + +### Linux glibc floor + +- The Linux job builds inside `almalinux:8` (glibc 2.28) so the binary runs on any glibc 2.28 or newer system. The `Check glibc floor` step fails when the binary references a newer `GLIBC_*` symbol version, which can happen after a toolchain or dependency change. +- `adc-linux-smoke` runs the built binary in Debian 11, Debian 12, Ubuntu 22.04 and Ubuntu 24.04 containers for both architectures. It runs after the archives are uploaded, so a failure does not block the upload. +- The binary is not static. Alpine and other musl systems need a glibc compatibility layer, which is not a supported target. +- The Linux job uses a container, so it can only use the JavaScript actions and shell tools available in that image. Install extra tools in the `Install build dependencies` step. + +## Docker images + +`docker.yaml` builds the images described in [libs/tools/README.md](../../libs/tools/README.md#docker-images). It runs on pushes to `main`, tags and pull requests, but only pushes images on `push` events. diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index e54b1a9d..a5ffa0d5 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -24,6 +24,7 @@ jobs: push: ${{ github.event_name == 'push' }} platforms: linux/amd64,linux/arm64 file: libs/tools/src/docker/Dockerfile + job-name-prefix: rust meta-images: | docker.io/api7/adc ghcr.io/api7/adc @@ -38,3 +39,30 @@ jobs: - registry: ghcr.io username: '${{ github.actor }}' password: '${{ secrets.GITHUB_TOKEN }}' + + build-js: + uses: docker/github-builder/.github/workflows/build.yml@c4a1b216d96a8c85b45a9974b37857828274c808 # v1.13.0 + permissions: + contents: read + packages: write + id-token: write + with: + output: image + push: ${{ github.event_name == 'push' }} + platforms: linux/amd64,linux/arm64 + file: libs/tools/src/docker/Dockerfile.js + job-name-prefix: js + meta-images: | + docker.io/api7/adc + ghcr.io/api7/adc + meta-tags: | + type=semver,pattern={{version}}-js + type=raw,value=dev-js,enable={{is_default_branch}} + secrets: + registry-auths: | + - registry: docker.io + username: '${{ secrets.DOCKER_USERNAME }}' + password: '${{ secrets.DOCKER_PASSWORD }}' + - registry: ghcr.io + username: '${{ github.actor }}' + password: '${{ secrets.GITHUB_TOKEN }}' diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index d9ba909e..fbe52ca7 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -10,7 +10,7 @@ on: env: NODE_VERSION: "24.16.0" jobs: - adc: + adc-js: if: startsWith(github.ref, 'refs/tags/') runs-on: ubuntu-latest permissions: @@ -43,25 +43,25 @@ jobs: run: | mkdir -p release mv ./node-binary/linux-amd64 ./adc - tar -czf release/adc_${{ env.RELEASE_VERSION }}_linux_amd64.tar.gz ./adc && rm -rf ./adc + tar -czf release/adc_js_${{ env.RELEASE_VERSION }}_linux_amd64.tar.gz ./adc && rm -rf ./adc mv ./node-binary/linux-arm64 ./adc - tar -czf release/adc_${{ env.RELEASE_VERSION }}_linux_arm64.tar.gz ./adc && rm -rf ./adc + tar -czf release/adc_js_${{ env.RELEASE_VERSION }}_linux_arm64.tar.gz ./adc && rm -rf ./adc mv ./node-binary/win-x64.exe ./adc.exe - zip -r release/adc_${{ env.RELEASE_VERSION }}_windows_amd64.zip ./adc.exe && rm -rf ./adc.exe + zip -r release/adc_js_${{ env.RELEASE_VERSION }}_windows_amd64.zip ./adc.exe && rm -rf ./adc.exe mv ./node-binary/win-arm64.exe ./adc.exe - zip -r release/adc_${{ env.RELEASE_VERSION }}_windows_arm64.zip ./adc.exe && rm -rf ./adc.exe + zip -r release/adc_js_${{ env.RELEASE_VERSION }}_windows_arm64.zip ./adc.exe && rm -rf ./adc.exe - name: Upload ADC to GitHub release uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3 if: startsWith(github.ref, 'refs/tags/') with: files: | - release/adc_${{ env.RELEASE_VERSION }}_linux_amd64.tar.gz - release/adc_${{ env.RELEASE_VERSION }}_linux_arm64.tar.gz - release/adc_${{ env.RELEASE_VERSION }}_windows_amd64.zip - release/adc_${{ env.RELEASE_VERSION }}_windows_arm64.zip + release/adc_js_${{ env.RELEASE_VERSION }}_linux_amd64.tar.gz + release/adc_js_${{ env.RELEASE_VERSION }}_linux_arm64.tar.gz + release/adc_js_${{ env.RELEASE_VERSION }}_windows_amd64.zip + release/adc_js_${{ env.RELEASE_VERSION }}_windows_arm64.zip - adc-macos: + adc-js-macos: if: startsWith(github.ref, 'refs/tags/') runs-on: macos-26 permissions: @@ -95,19 +95,19 @@ jobs: run: | mkdir release mv ./node-binary/darwin-arm64 ./adc - tar -czf release/adc_${{ env.RELEASE_VERSION }}_darwin_arm64.tar.gz ./adc && rm -rf ./adc + tar -czf release/adc_js_${{ env.RELEASE_VERSION }}_darwin_arm64.tar.gz ./adc && rm -rf ./adc mv ./node-binary/darwin-x64 ./adc - tar -czf release/adc_${{ env.RELEASE_VERSION }}_darwin_amd64.tar.gz ./adc && rm -rf ./adc + tar -czf release/adc_js_${{ env.RELEASE_VERSION }}_darwin_amd64.tar.gz ./adc && rm -rf ./adc - name: Upload ADC to GitHub release uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3 if: startsWith(github.ref, 'refs/tags/') with: files: | - release/adc_${{ env.RELEASE_VERSION }}_darwin_arm64.tar.gz - release/adc_${{ env.RELEASE_VERSION }}_darwin_amd64.tar.gz + release/adc_js_${{ env.RELEASE_VERSION }}_darwin_arm64.tar.gz + release/adc_js_${{ env.RELEASE_VERSION }}_darwin_amd64.tar.gz - adc-rust-linux: + adc-linux: if: startsWith(github.ref, 'refs/tags/') || contains(github.event.pull_request.labels.*.name, 'test/build') strategy: fail-fast: false @@ -118,9 +118,15 @@ jobs: - os: ubuntu-24.04-arm arch: arm64 runs-on: ${{ matrix.os }} + # Built on EL8 so the binary only needs glibc 2.28 or newer at runtime. + container: almalinux:8 permissions: contents: write steps: + - name: Install build dependencies + run: | + dnf install -y gcc-toolset-12-gcc gcc-toolset-12-binutils make cmake perl git tar gzip curl + echo "/opt/rh/gcc-toolset-12/root/usr/bin" >> $GITHUB_PATH - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false @@ -132,10 +138,19 @@ jobs: echo "RELEASE_VERSION=pr-${{ github.event.pull_request.number }}" >> $GITHUB_ENV fi + - name: Verify tag matches Cargo version + if: startsWith(github.ref, 'refs/tags/') + run: | + CARGO_VERSION=$(sed -n '/^\[workspace.package\]/,/^\[/s/^version = "\(.*\)"/\1/p' rust/Cargo.toml) + if [ "$CARGO_VERSION" != "$RELEASE_VERSION" ]; then + echo "Tag version $RELEASE_VERSION does not match rust/Cargo.toml version $CARGO_VERSION" + exit 1 + fi + - name: Setup Rust toolchain run: | - rustup update stable - rustup default stable + curl -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain stable + echo "$HOME/.cargo/bin" >> $GITHUB_PATH - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 with: workspaces: rust -> target @@ -144,6 +159,15 @@ jobs: working-directory: ./rust run: cargo build --release -p adc-cli + - name: Check glibc floor + run: | + MAX=$(objdump -T rust/target/release/adc | grep -o 'GLIBC_[0-9.]*' | sort -uV | tail -1) + echo "Highest required glibc symbol version: $MAX" + if [ "$(printf '%s\n' "$MAX" GLIBC_2.28 | sort -V | tail -1)" != "GLIBC_2.28" ]; then + echo "Binary requires $MAX, which is newer than the supported GLIBC_2.28" + exit 1 + fi + - name: Split debug info run: | BIN_DIR=rust/target/release @@ -155,28 +179,51 @@ jobs: run: | mkdir -p release BIN_DIR=rust/target/release - tar -czf release/adc_rust_${{ env.RELEASE_VERSION }}_linux_${{ matrix.arch }}.tar.gz -C "$BIN_DIR" adc - tar -czf release/adc_rust_${{ env.RELEASE_VERSION }}_linux_${{ matrix.arch }}_debuginfo.tar.gz -C "$BIN_DIR" adc.debug + tar -czf release/adc_${{ env.RELEASE_VERSION }}_linux_${{ matrix.arch }}.tar.gz -C "$BIN_DIR" adc + tar -czf release/adc_${{ env.RELEASE_VERSION }}_linux_${{ matrix.arch }}_debuginfo.tar.gz -C "$BIN_DIR" adc.debug - name: Upload adc to GitHub release uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3 if: startsWith(github.ref, 'refs/tags/') with: files: | - release/adc_rust_${{ env.RELEASE_VERSION }}_linux_${{ matrix.arch }}.tar.gz - release/adc_rust_${{ env.RELEASE_VERSION }}_linux_${{ matrix.arch }}_debuginfo.tar.gz + release/adc_${{ env.RELEASE_VERSION }}_linux_${{ matrix.arch }}.tar.gz + release/adc_${{ env.RELEASE_VERSION }}_linux_${{ matrix.arch }}_debuginfo.tar.gz - name: Upload adc artifact uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - if: github.event_name == 'pull_request' with: - name: adc_rust_linux_${{ matrix.arch }} + name: adc_linux_${{ matrix.arch }} path: | - release/adc_rust_${{ env.RELEASE_VERSION }}_linux_${{ matrix.arch }}.tar.gz - release/adc_rust_${{ env.RELEASE_VERSION }}_linux_${{ matrix.arch }}_debuginfo.tar.gz + release/adc_${{ env.RELEASE_VERSION }}_linux_${{ matrix.arch }}.tar.gz + release/adc_${{ env.RELEASE_VERSION }}_linux_${{ matrix.arch }}_debuginfo.tar.gz if-no-files-found: error - adc-rust-windows: + adc-linux-smoke: + needs: adc-linux + strategy: + fail-fast: false + matrix: + arch: [amd64, arm64] + image: ["debian:11", "debian:12", "ubuntu:22.04", "ubuntu:24.04"] + include: + - arch: amd64 + os: ubuntu-latest + - arch: arm64 + os: ubuntu-24.04-arm + runs-on: ${{ matrix.os }} + steps: + - name: Download adc artifact + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 + with: + name: adc_linux_${{ matrix.arch }} + - name: Run adc in ${{ matrix.image }} + run: | + mkdir bin + tar -xzf adc_*_linux_${{ matrix.arch }}.tar.gz -C bin + docker run --rm -v "$PWD/bin:/opt/adc:ro" ${{ matrix.image }} sh -c '/opt/adc/adc --version && /opt/adc/adc --help > /dev/null' + + adc-windows: if: startsWith(github.ref, 'refs/tags/') || contains(github.event.pull_request.labels.*.name, 'test/build') strategy: fail-fast: false @@ -220,28 +267,28 @@ jobs: run: | New-Item -ItemType Directory -Force -Path release | Out-Null $binDir = "rust/target/release" - Compress-Archive -Path "$binDir/adc.exe" -DestinationPath "release/adc_rust_${{ env.RELEASE_VERSION }}_windows_${{ matrix.arch }}.zip" - Compress-Archive -Path "$binDir/adc.pdb" -DestinationPath "release/adc_rust_${{ env.RELEASE_VERSION }}_windows_${{ matrix.arch }}_debuginfo.zip" + Compress-Archive -Path "$binDir/adc.exe" -DestinationPath "release/adc_${{ env.RELEASE_VERSION }}_windows_${{ matrix.arch }}.zip" + Compress-Archive -Path "$binDir/adc.pdb" -DestinationPath "release/adc_${{ env.RELEASE_VERSION }}_windows_${{ matrix.arch }}_debuginfo.zip" - name: Upload adc to GitHub release uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3 if: startsWith(github.ref, 'refs/tags/') with: files: | - release/adc_rust_${{ env.RELEASE_VERSION }}_windows_${{ matrix.arch }}.zip - release/adc_rust_${{ env.RELEASE_VERSION }}_windows_${{ matrix.arch }}_debuginfo.zip + release/adc_${{ env.RELEASE_VERSION }}_windows_${{ matrix.arch }}.zip + release/adc_${{ env.RELEASE_VERSION }}_windows_${{ matrix.arch }}_debuginfo.zip - name: Upload adc artifact uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 if: github.event_name == 'pull_request' with: - name: adc_rust_windows_${{ matrix.arch }} + name: adc_windows_${{ matrix.arch }} path: | - release/adc_rust_${{ env.RELEASE_VERSION }}_windows_${{ matrix.arch }}.zip - release/adc_rust_${{ env.RELEASE_VERSION }}_windows_${{ matrix.arch }}_debuginfo.zip + release/adc_${{ env.RELEASE_VERSION }}_windows_${{ matrix.arch }}.zip + release/adc_${{ env.RELEASE_VERSION }}_windows_${{ matrix.arch }}_debuginfo.zip if-no-files-found: error - adc-rust-macos: + adc-macos: if: startsWith(github.ref, 'refs/tags/') || contains(github.event.pull_request.labels.*.name, 'test/build') strategy: fail-fast: false @@ -288,23 +335,23 @@ jobs: run: | mkdir -p release BIN_DIR=rust/target/${{ matrix.target }}/release - tar -czf release/adc_rust_${{ env.RELEASE_VERSION }}_darwin_${{ matrix.arch }}.tar.gz -C "$BIN_DIR" adc - tar -czf release/adc_rust_${{ env.RELEASE_VERSION }}_darwin_${{ matrix.arch }}_debuginfo.tar.gz -C "$BIN_DIR" adc.dSYM + tar -czf release/adc_${{ env.RELEASE_VERSION }}_darwin_${{ matrix.arch }}.tar.gz -C "$BIN_DIR" adc + tar -czf release/adc_${{ env.RELEASE_VERSION }}_darwin_${{ matrix.arch }}_debuginfo.tar.gz -C "$BIN_DIR" adc.dSYM - name: Upload adc to GitHub release uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3 if: startsWith(github.ref, 'refs/tags/') with: files: | - release/adc_rust_${{ env.RELEASE_VERSION }}_darwin_${{ matrix.arch }}.tar.gz - release/adc_rust_${{ env.RELEASE_VERSION }}_darwin_${{ matrix.arch }}_debuginfo.tar.gz + release/adc_${{ env.RELEASE_VERSION }}_darwin_${{ matrix.arch }}.tar.gz + release/adc_${{ env.RELEASE_VERSION }}_darwin_${{ matrix.arch }}_debuginfo.tar.gz - name: Upload adc artifact uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 if: github.event_name == 'pull_request' with: - name: adc_rust_darwin_${{ matrix.arch }} + name: adc_darwin_${{ matrix.arch }} path: | - release/adc_rust_${{ env.RELEASE_VERSION }}_darwin_${{ matrix.arch }}.tar.gz - release/adc_rust_${{ env.RELEASE_VERSION }}_darwin_${{ matrix.arch }}_debuginfo.tar.gz + release/adc_${{ env.RELEASE_VERSION }}_darwin_${{ matrix.arch }}.tar.gz + release/adc_${{ env.RELEASE_VERSION }}_darwin_${{ matrix.arch }}_debuginfo.tar.gz if-no-files-found: error diff --git a/README.md b/README.md index 738636d1..8f2168b5 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,8 @@ Or, you can download the appropriate binary from the [releases page](https://git Pre-built binaries for `amd64` and `arm64` on Linux, Windows, and macOS are available now. +The binaries and the Docker images (`api7/adc:`, also published to `ghcr.io/api7/adc`) are the Rust implementation. The JavaScript implementation is published as `adc_js___` archives and `api7/adc:-js` images. The Linux binaries require glibc 2.28 or newer. See [Workflows](.github/workflows/README.md) and [tools](libs/tools/README.md) for the release details. + ## Configure ADC You can configure ADC through environment variables or command line flags. Run `adc help [command]` to see the available configuration options for a command. diff --git a/libs/tools/README.md b/libs/tools/README.md new file mode 100644 index 00000000..f6097d15 --- /dev/null +++ b/libs/tools/README.md @@ -0,0 +1,23 @@ +# tools + +Distribution assets that are not part of the CLI itself. + +## Docker images + +Both images are published to `docker.io/api7/adc` and `ghcr.io/api7/adc` by `.github/workflows/docker.yaml`, for `linux/amd64` and `linux/arm64`. + +| Dockerfile | Implementation | Tags | +|---|---|---| +| `src/docker/Dockerfile` | Rust | ``, `dev` | +| `src/docker/Dockerfile.js` | JavaScript | `-js`, `dev-js` | + +- The Rust image builds `adc-cli` in `rust:1-trixie` and runs it on `gcr.io/distroless/cc-debian13:nonroot`. The runtime image provides glibc, libgcc and CA certificates, so the binary must stay glibc based. Moving to a static musl binary would require changing the base image as well. +- The Docker build context is the repository root. `.dockerignore` excludes `rust/target` and `node_modules`, keep them excluded or the context becomes very large. +- The entrypoint of each image is the CLI binary itself, so arguments are passed straight to `adc`. + +## Install script + +`src/s3/install` is what `https://run.api7.ai/adc/install` serves. `.github/workflows/update-s3-and-cloudfront.yaml` syncs it to S3 on every merge to `main`, independent of any release tag. + +- It downloads `adc___.tar.gz` from the GitHub release, which is the Rust build. The file names are defined in [.github/workflows/README.md](../../.github/workflows/README.md#release-artifacts), keep both in step. +- The architecture mapping only converts `x86_64` to `amd64`. On Linux arm64 `uname -m` reports `aarch64`, which is not mapped. diff --git a/libs/tools/src/docker/Dockerfile b/libs/tools/src/docker/Dockerfile index b51f2ed6..8990000a 100644 --- a/libs/tools/src/docker/Dockerfile +++ b/libs/tools/src/docker/Dockerfile @@ -1,20 +1,13 @@ -FROM node:lts-bookworm-slim AS builder - -ENV PNPM_HOME="/pnpm" -ENV PATH="$PNPM_HOME/bin:$PATH" -ENV NX_DAEMON="false" -RUN corepack enable +FROM rust:1-trixie AS builder WORKDIR /build -COPY . . +COPY rust ./rust -RUN pnpm install nx -g \ - && pnpm install \ - && NODE_ENV=production nx build cli +RUN cd rust && cargo build --release --locked -p adc-cli -FROM gcr.io/distroless/nodejs24-debian13:nonroot +FROM gcr.io/distroless/cc-debian13:nonroot -COPY --from=builder /build/dist/apps/cli/main.cjs . +COPY --from=builder /build/rust/target/release/adc /adc -ENTRYPOINT [ "/nodejs/bin/node", "main.cjs" ] +ENTRYPOINT [ "/adc" ] diff --git a/libs/tools/src/docker/Dockerfile.js b/libs/tools/src/docker/Dockerfile.js new file mode 100644 index 00000000..b51f2ed6 --- /dev/null +++ b/libs/tools/src/docker/Dockerfile.js @@ -0,0 +1,20 @@ +FROM node:lts-bookworm-slim AS builder + +ENV PNPM_HOME="/pnpm" +ENV PATH="$PNPM_HOME/bin:$PATH" +ENV NX_DAEMON="false" +RUN corepack enable + +WORKDIR /build + +COPY . . + +RUN pnpm install nx -g \ + && pnpm install \ + && NODE_ENV=production nx build cli + +FROM gcr.io/distroless/nodejs24-debian13:nonroot + +COPY --from=builder /build/dist/apps/cli/main.cjs . + +ENTRYPOINT [ "/nodejs/bin/node", "main.cjs" ] From 2b89987de6b7d1030c10f5e050b9dcd79688b69d Mon Sep 17 00:00:00 2001 From: bzp2010 Date: Mon, 26 Oct 2026 14:10:31 +0800 Subject: [PATCH 2/3] ci(release): limit smoke job token permissions --- .github/workflows/release.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index fbe52ca7..d525fc68 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -212,6 +212,8 @@ jobs: - arch: arm64 os: ubuntu-24.04-arm runs-on: ${{ matrix.os }} + permissions: + contents: read steps: - name: Download adc artifact uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 From 9a6874a42e4162dd3399b23cd9f512126ff4fa70 Mon Sep 17 00:00:00 2001 From: bzp2010 Date: Mon, 26 Oct 2026 14:30:33 +0800 Subject: [PATCH 3/3] ci(docker): keep the latest tag on the Rust image and document both builds Disable the automatic latest tag for the JS image so it cannot overwrite the Rust one, and split the README development section into Rust and JavaScript builds. --- .github/workflows/docker.yaml | 1 + README.md | 14 +++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index a5ffa0d5..2576b760 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -58,6 +58,7 @@ jobs: meta-tags: | type=semver,pattern={{version}}-js type=raw,value=dev-js,enable={{is_default_branch}} + meta-flavor: latest=false secrets: registry-auths: | - registry: docker.io diff --git a/README.md b/README.md index 8f2168b5..cdccce89 100644 --- a/README.md +++ b/README.md @@ -108,7 +108,19 @@ See the [`docs/`](docs/README.md) folder for the CLI command reference, configur ## Development -To build ADC from source, [install Nx](https://nx.dev/getting-started/installation) and run: +### Rust CLI + +The default `adc` binary is built with Cargo: + +```bash +cd rust +cargo build --release -p adc-cli +./target/release/adc -h +``` + +### JavaScript CLI + +To build the JavaScript implementation, [install Nx](https://nx.dev/getting-started/installation) and run: ```bash pnpm install