diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 71600bf..2ff263e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -230,3 +230,78 @@ jobs: --repo "$TARGET_REPO" \ --title "chore: vendor installer scripts ${TAG}" \ --body "Vendors install.sh/install.ps1 from ${SOURCE_REPO}@${TAG} (commit ${GITHUB_SHA})." + + publish-cloudsmith: + name: Publish to Cloudsmith + needs: release + if: ${{ vars.CLOUDSMITH_SERVICE_SLUG != '' }} + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write # needed for the CLI to exchange the GitHub Actions OIDC token + env: + # Consumed automatically by the CLI's GitHub Actions OIDC exchange. + CLOUDSMITH_ORG: ${{ vars.CLOUDSMITH_NAMESPACE }} + CLOUDSMITH_SERVICE_SLUG: ${{ vars.CLOUDSMITH_SERVICE_SLUG }} + CLOUDSMITH_NAMESPACE: ${{ vars.CLOUDSMITH_NAMESPACE }} + CLOUDSMITH_REPO: ${{ vars.CLOUDSMITH_REPO }} + TAG: ${{ github.ref_name }} + steps: + - name: Checkout + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false + + - name: Install the Cloudsmith CLI using install.sh + run: | + set -eu + output="$(sh ./install.sh --version latest)" + printf '%s\n' "$output" + executable="$(printf '%s\n' "$output" | grep '^executable=' | cut -d= -f2-)" + test -n "$executable" + echo "CLOUDSMITH_BIN=$executable" >> "$GITHUB_ENV" + + # The scripts are published as cli.sh and cli.ps1, served at + # https://install.cloudsmith.com/raw/files/cli.. + - name: Stage scripts under their published names + run: | + set -eu + cp install.sh cli.sh + cp install.ps1 cli.ps1 + sha256sum cli.sh cli.ps1 > SHA256SUMS + + - name: Authenticate via GitHub OIDC + run: | + set -eu + "$CLOUDSMITH_BIN" whoami + + - name: Push install scripts + run: | + set -eu + VERSION="${TAG#v}" + for file in cli.sh cli.ps1 SHA256SUMS; do + "$CLOUDSMITH_BIN" push raw \ + "$CLOUDSMITH_NAMESPACE/$CLOUDSMITH_REPO" \ + "$file" \ + --name "$file" \ + --version "$VERSION" \ + --republish + done + + - name: Verify published files + run: | + set -eu + VERSION="${TAG#v}" + for file in cli.sh cli.ps1 SHA256SUMS; do + url="https://dl.cloudsmith.io/public/$CLOUDSMITH_NAMESPACE/$CLOUDSMITH_REPO/raw/names/$file/versions/$VERSION/$file" + expected="$(sha256sum "$file" | awk '{print $1}')" + if ! actual="$(curl -fsSL "$url" | sha256sum | awk '{print $1}')"; then + echo "notice: could not download $url (repository may still be private); skipping verification" + continue + fi + if [ "$expected" != "$actual" ]; then + echo "checksum mismatch for $url" >&2 + exit 1 + fi + echo "verified $url" + done diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ecfe76..f132895 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Release workflow job publishing the install scripts to Cloudsmith as + `cli.sh` and `cli.ps1` (with `SHA256SUMS`), gated on configuration and + authenticated via the CLI's GitHub Actions OIDC exchange. Served at + `https://install.cloudsmith.com/raw/files/cli.`. +- README instructions for installing from the published Cloudsmith URLs. + ## [0.1.0] - 2026-07-16 ### Added diff --git a/README.md b/README.md index 3077482..fc037a2 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,29 @@ sh ./install.sh --version latest On success, use the reported `bin_dir` to update `PATH`, or invoke the reported `executable` directly. +### Install from Cloudsmith + +Tagged releases are also published to Cloudsmith as `cli.sh` and `cli.ps1`, +served at stable short URLs. Install the latest CLI with one command: + +```sh +curl -fsSL https://install.cloudsmith.com/raw/files/cli.sh | sh +``` + +```powershell +irm https://install.cloudsmith.com/raw/files/cli.ps1 | iex +``` + +Both scripts install the latest CLI version by default and print the +installed `bin_dir` to add to `PATH`. + +To verify before running, or to pin a version, download the script and +`SHA256SUMS` from +`https://dl.cloudsmith.io/public/cloudsmith/cloudsmith-cli-install-script/raw/names//versions//` +where `` is `cli.sh`, `cli.ps1`, or `SHA256SUMS`, then run it with +`--version X.Y.Z` (`-Version X.Y.Z` in PowerShell). Use pinned, verified +downloads in CI. + ## How installation works ```mermaid