Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 109 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,13 @@ jobs:
- uses: actions/setup-go@v7
with:
go-version-file: go.mod
- name: Binaries, archives, the GitHub release and the Homebrew cask
# The key the agent's packages are signed with, so apt and yum trust the CLI's too.
# Outside the checkout: goreleaser refuses to release from a tree with untracked files.
- name: Export the package signing key
env:
SECRET: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }}
run: echo -n "$SECRET" > "$RUNNER_TEMP/gpg.key"
- name: Binaries, archives, Linux packages, the GitHub release and the Homebrew cask
uses: goreleaser/goreleaser-action@v7
with:
version: '~> v2'
Expand All @@ -167,6 +173,11 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Pushes the cask to steadybit/homebrew-tap, which GITHUB_TOKEN cannot write to.
HOMEBREW_TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
NFPM_KEY_FILE: ${{ runner.temp }}/gpg.key
NFPM_PASSPHRASE: ${{ secrets.MAVEN_GPG_PRIVATE_KEY_PASSWORD }}
- name: Remove the package signing key
if: always()
run: rm -f "$RUNNER_TEMP/gpg.key"
# `uses: steadybit/cli@v6` resolves through the major tag, so each stable release
# moves it. A push with GITHUB_TOKEN triggers no workflow, so the tag does not start
# another release.
Expand All @@ -183,6 +194,103 @@ jobs:
with:
command: monitor

# The signed packages of a release, installed before they are published to the apt and yum
# repositories. A job of its own, so that a failing upload leaves the release, the cask and
# the major tag in place and does not skip verify-action.
release-linux-packages:
if: startsWith(github.ref, 'refs/tags/v')
needs: release
runs-on: ubuntu-latest
permissions:
contents: read
# Uploading authenticates to Google Cloud as the workflow.
id-token: write
steps:
- name: Download the packages from the release
env:
GH_TOKEN: ${{ github.token }}
run: |
gh release download "${GITHUB_REF_NAME}" --repo "${GITHUB_REPOSITORY}" \
--dir packages --pattern 'steadybit-cli_*.deb' --pattern 'steadybit-cli_*.rpm'
ls -l packages
- name: Install the .deb and run it
run: |
sudo apt-get install -y ./packages/steadybit-cli_amd64.deb
steadybit -V
test "$(steadybit -V)" = "${GITHUB_REF_NAME#v}"
# Off until Google Cloud lets this repository upload: the workload identity provider
# has to trust steadybit/cli first. The repository variable turns it on. Prereleases
# stay off the repositories, as they stay off releases/latest.
- name: Publish the Linux packages to packages.steadybit.com
if: ${{ !contains(github.ref_name, '-') && vars.PUBLISH_LINUX_PACKAGES == 'true' }}
uses: steadybit/.github/actions/gar-upload-linux-packages@main
with:
workload_identity_provider: ${{ secrets.GCP_ARTIFACT_REGISTRY_IDENTITY_PROVIDER }}
service_account: ${{ vars.GCP_ARTIFACT_REGISTRY_PROJECT_SA }}
project_id: ${{ vars.GCP_ARTIFACT_REGISTRY_PROJECT_ID }}
location: ${{ vars.GCP_ARTIFACT_REGISTRY_PROJECT_LOCATION }}
deb_repository: deb-public
yum_repository: yum-public
packages_dir: ./packages

# The packages of every build, installed and run on the distributions they are for. On
# main they are also signed and go to the dev repositories, which is how the upload is
# checked before a release depends on it. Other refs, pull requests and branches started
# by hand, build them unsigned and upload nothing, so the production key signs only main.
linux-packages:
if: github.event_name != 'schedule' && !startsWith(github.ref, 'refs/tags/')
# As docker-build: nothing reaches the dev repositories from a build whose checks fail.
needs: [verify, api-compatibility]
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
- uses: actions/setup-go@v7
with:
go-version-file: go.mod
- name: Export the package signing key
if: github.ref == 'refs/heads/main'
env:
SECRET: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }}
run: |
echo -n "$SECRET" > "$RUNNER_TEMP/gpg.key"
echo "NFPM_KEY_FILE=$RUNNER_TEMP/gpg.key" >> "$GITHUB_ENV"
- name: Build the packages
uses: goreleaser/goreleaser-action@v7
with:
version: '~> v2'
args: release --snapshot --clean
env:
HOMEBREW_TAP_TOKEN: unused
NFPM_PASSPHRASE: ${{ secrets.MAVEN_GPG_PRIVATE_KEY_PASSWORD }}
- name: Remove the package signing key
if: always()
run: rm -f "$RUNNER_TEMP/gpg.key"
- name: Install the .deb and run it
run: |
sudo apt-get install -y ./dist/steadybit-cli_amd64.deb
steadybit -V
test -f /usr/share/bash-completion/completions/steadybit
- name: Install the .rpm and run it
run: |
docker run --rm -v "$PWD/dist:/dist" fedora:latest \
sh -c 'dnf install -y -q /dist/steadybit-cli_amd64.rpm && steadybit -V'
- name: Publish to the dev repositories
if: github.ref == 'refs/heads/main' && vars.PUBLISH_LINUX_PACKAGES == 'true'
uses: steadybit/.github/actions/gar-upload-linux-packages@main
with:
workload_identity_provider: ${{ secrets.GCP_ARTIFACT_REGISTRY_IDENTITY_PROVIDER }}
service_account: ${{ vars.GCP_ARTIFACT_REGISTRY_PROJECT_SA }}
project_id: ${{ vars.GCP_ARTIFACT_REGISTRY_PROJECT_ID }}
location: ${{ vars.GCP_ARTIFACT_REGISTRY_PROJECT_LOCATION }}
deb_repository: deb-dev
yum_repository: yum-dev
packages_dir: ./dist

# The action downloads from the release, so it can only be checked once one exists.
verify-action:
if: startsWith(github.ref, 'refs/tags/v')
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,6 @@ node_modules
.env.local
.env.*.local
/completions

# The package signing key, should a job ever write it into the checkout.
/gpg.key
39 changes: 38 additions & 1 deletion .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,48 @@ archives:
formats: [zip]
files: [LICENSE, README.md, CHANGELOG.md, completions/*]

# .deb and .rpm packages for Linux, attached to the release and published to the apt and
# yum repositories at packages.steadybit.com, next to steadybit-agent. Without the version
# in the file name, as the archives, so that releases/latest/download/<name> is stable.
nfpms:
- id: steadybit
package_name: steadybit-cli
file_name_template: '{{ .PackageName }}_{{ .Arch }}'
formats: [deb, rpm]
vendor: Steadybit GmbH
homepage: https://github.com/steadybit/cli
maintainer: Steadybit <support@steadybit.com>
description: Command-line interface for the Steadybit chaos engineering platform
license: MIT
contents:
- src: completions/steadybit.bash
dst: /usr/share/bash-completion/completions/steadybit
# Debian and Ubuntu read zsh completions from vendor-completions; Fedora, RHEL and
# Amazon Linux only from site-functions.
- src: completions/_steadybit
dst: /usr/share/zsh/vendor-completions/_steadybit
packager: deb
- src: completions/_steadybit
dst: /usr/share/zsh/site-functions/_steadybit
packager: rpm
- src: completions/steadybit.fish
dst: /usr/share/fish/vendor_completions.d/steadybit.fish
- src: LICENSE
dst: /usr/share/doc/steadybit-cli/copyright
# Signed with the key the agent's packages are signed with, when CI provides it; a
# local snapshot builds them unsigned.
deb:
signature:
key_file: '{{ envOrDefault "NFPM_KEY_FILE" "" }}'
rpm:
signature:
key_file: '{{ envOrDefault "NFPM_KEY_FILE" "" }}'

checksum:
name_template: checksums.txt

snapshot:
version_template: '{{ incpatch .Version }}-next'
version_template: '{{ incpatch .Version }}-{{ .CommitTimestamp }}-next'

release:
# The changelog is written by hand in CHANGELOG.md.
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@
- Experiment templates, environments, teams, property definitions, hubs and integrations
have a `diff`, and their `apply` a `--dry-run`. The actions a team is given when sent
none, and the target attributes a webhook reports when sent none, are not differences.
- Linux packages: a signed `steadybit-cli` `.deb` and `.rpm`, with shell completions, are
attached to every release (`steadybit-cli_amd64.deb`, `steadybit-cli_arm64.rpm`, …).

## v6.0.1

Expand Down
6 changes: 5 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,11 @@ not generated structs, so that fields the spec does not know yet are never dropp
## Releasing

Releases are published by CI, not from a workstation: pushing a `v*` tag builds the
binaries with goreleaser, creates the GitHub release with them, pushes the Homebrew cask to
binaries and the signed `.deb`/`.rpm` packages with goreleaser, creates the GitHub release
with them, publishes the packages to the apt and yum repositories at packages.steadybit.com (when
the repository variable `PUBLISH_LINUX_PACKAGES` is `true`; that needs the Google Cloud
workload identity provider to trust `steadybit/cli`),
pushes the Homebrew cask to
[steadybit/homebrew-tap](https://github.com/steadybit/homebrew-tap), and pushes the Docker
image. The cask needs the `HOMEBREW_TAP_TOKEN` secret, a token that can write to that
repository. A stable release also moves the major tag (`v6`) that `uses: steadybit/cli@v6`
Expand Down
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,18 @@ completions:
brew install steadybit/tap/steadybit
```

On Debian, Ubuntu, Fedora or RHEL, install the package attached to every release from
v6.1.0 on, which also installs the shell completions:

```sh
# Debian, Ubuntu
curl -fsSLO https://github.com/steadybit/cli/releases/latest/download/steadybit-cli_amd64.deb
sudo apt-get install ./steadybit-cli_amd64.deb
# Fedora, RHEL, Amazon Linux
curl -fsSLO https://github.com/steadybit/cli/releases/latest/download/steadybit-cli_amd64.rpm
sudo dnf install ./steadybit-cli_amd64.rpm
```

Or download the archive for your platform from the
[releases](https://github.com/steadybit/cli/releases) (`checksums.txt` lists their SHA-256)
and put `steadybit` on your `PATH`:
Expand Down
Loading