From 42b09b2b8a6bca4b660298441499e1118dc3f540 Mon Sep 17 00:00:00 2001 From: Supesharisuto Date: Wed, 14 Oct 2026 14:41:23 +0700 Subject: [PATCH] ci: test and run the binary on arm64; arm64-first builds release.go has built darwin/arm64 and linux/arm64 for a while, but CI and the release gates ran on ubuntu-latest only, so the arm64 binaries were cross-compiled and never executed, and the tests never ran on arm64. (OpenSystemsLab/awless-ro#1) - ci.yml and release.yml get an arm64 job on GitHub's free hosted runners, ubuntu-24.04-arm and macos-latest (Apple Silicon): go test -race, then build and run the binary. The release is published only after it passes. The other gates are architecture-independent and still run once, on ubuntu-latest. - make build defaults to GOARCH=arm64, overridable, and unexported so that generate and test run on the host. release.go and the README's install section list arm64 first. The Homebrew formula already picks the arm64 archive under on_arm and the amd64 one under on_intel, for macOS and Linux; nothing to change there. --- .github/workflows/ci.yml | 31 +++++++++++++++++++++++++++++++ .github/workflows/release.yml | 34 ++++++++++++++++++++++++++++++++++ CHANGELOG.md | 9 +++++++++ CONTRIBUTING.md | 8 ++++++++ Makefile | 11 +++++++++-- README.md | 11 +++++++++++ release.go | 8 +++++--- 7 files changed, 107 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bf4d2f70..e439b8c8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -78,3 +78,34 @@ jobs: # there is one less third party in the chain. - name: actionlint run: go run github.com/rhysd/actionlint/cmd/actionlint@v1.7.12 + + # The same code on arm64, natively: release.go publishes darwin/arm64 and + # linux/arm64 binaries, and they are cross-compiled on amd64, so without this job + # neither the tests nor the binary would ever run on arm64. GitHub-hosted, free for + # public repositories: ubuntu-24.04-arm is Linux on arm64, macos-latest Apple + # Silicon. Only what depends on the architecture runs here; the other gates are + # the same everywhere and run once, in build. + arm64: + strategy: + fail-fast: false + matrix: + os: [ubuntu-24.04-arm, macos-latest] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 + with: + go-version: '1.26' + check-latest: true + + - name: go test + run: go test ./... -race + + - name: run the binary + run: | + go build -trimpath -o awless-ro . + echo "built for $(go env GOOS)/$(go env GOARCH) on $(uname -sm)" + ./awless-ro version + ./awless-ro --help > /dev/null diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 518a6c6f..44028c46 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,7 +13,41 @@ permissions: contents: read jobs: + # The same code on arm64, natively: release.go publishes darwin/arm64 and + # linux/arm64 binaries, and they are cross-compiled on amd64, so without this job + # neither the tests nor the binary would ever run on arm64. GitHub-hosted, free for + # public repositories: ubuntu-24.04-arm is Linux on arm64, macos-latest Apple + # Silicon. Only what depends on the architecture runs here; the other gates are + # the same everywhere and run once, in release. + arm64: + strategy: + fail-fast: false + matrix: + os: [ubuntu-24.04-arm, macos-latest] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 + with: + go-version: '1.26' + check-latest: true + + - name: go test + run: go test ./... -race + + - name: run the binary + run: | + go build -trimpath -o awless-ro . + echo "built for $(go env GOOS)/$(go env GOARCH) on $(uname -sm)" + ./awless-ro version + ./awless-ro --help > /dev/null + release: + # arm64 artefacts are published only once their tests and binary have run on + # arm64. + needs: arm64 runs-on: ubuntu-latest permissions: # To create the release and attach the artefacts. Nothing else. diff --git a/CHANGELOG.md b/CHANGELOG.md index b2f64090..5f392994 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## Unreleased + +### Changed + +- `make build` builds for arm64 unless `GOARCH` says otherwise; `release.go` and the + README's install section list the arm64 archives first. +- CI and the release workflow also run the tests and the binary on arm64, natively, + on GitHub's Linux arm64 and Apple Silicon runners. + ## v0.5.0 **Breaking:** `switch` with `-p` or `-r` now exits 1 without saving anything. Pass the diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ea222e32..8096d7aa 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -47,6 +47,14 @@ go mod verify go run golang.org/x/vuln/cmd/govulncheck@v1.8.0 ./... ``` +### Where CI runs + +On GitHub-hosted runners only. `build` runs every gate above on `ubuntu-latest`; +`arm64` runs the tests (with `-race`) and the built binary natively on +`ubuntu-24.04-arm` and `macos-latest` (Apple Silicon), because the arm64 release +artefacts are cross-compiled and would otherwise never be executed before they ship. +The Release workflow runs the same `arm64` job before it publishes anything. + ## Dependencies and the supply chain This project inherited its dependency list from a repository abandoned in 2018. One diff --git a/Makefile b/Makefile index c86799ec..2bc36a57 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,13 @@ generate: @echo "Generating commands code: runtime, doc, etc." @go generate gen/aws/generators/main.go +# arm64 by default: Apple Silicon and Graviton are the machines this is built for. +# Override for anything else, e.g. `make build GOARCH=amd64`, or with GOARCH in the +# environment. Only the binary is cross-built: make would otherwise export GOARCH to +# every recipe, and generate and test have to run on the host. +GOARCH ?= arm64 +unexport GOARCH + build: generate test - @echo "Building application binary" - @go build -trimpath -o awless-ro + @echo "Building application binary for $$(go env GOOS)/$(GOARCH)" + @GOARCH=$(GOARCH) go build -trimpath -o awless-ro diff --git a/README.md b/README.md index bdecacae..e625b58e 100644 --- a/README.md +++ b/README.md @@ -238,6 +238,14 @@ go install github.com/theazz/awless-ro@latest Or download a binary from [releases](https://github.com/theazz/awless-ro/releases) and verify it: +| Platform | Archive | +|---|---| +| macOS, Apple Silicon | `awless-ro-darwin-arm64.tar.gz` | +| Linux, arm64 (Graviton and other 64-bit ARM) | `awless-ro-linux-arm64.tar.gz` | +| macOS, Intel | `awless-ro-darwin-amd64.tar.gz` | +| Linux, x86-64 | `awless-ro-linux-amd64.tar.gz` | +| Windows, x86-64 | `awless-ro-windows-amd64.zip` | + ```sh shasum -a 256 -c SHA256SUMS --ignore-missing ``` @@ -249,6 +257,9 @@ git clone https://github.com/theazz/awless-ro && cd awless-ro go build -o awless-ro . ``` +`make build` builds for arm64 by default; `make build GOARCH=amd64` for an Intel +machine. + Requires Go 1.26. No configuration needed if you already use the AWS CLI: existing `~/.aws/{credentials,config}` profiles are picked up, and anything missing is prompted for on first run. With no profile chosen, credentials in diff --git a/release.go b/release.go index ea99783d..385ea5e0 100644 --- a/release.go +++ b/release.go @@ -46,10 +46,12 @@ var ( ) // 386 was dropped and arm64 added: Apple Silicon and Graviton are the platforms -// that matter now, and 32-bit x86 has not been a realistic target for years. +// that matter now, and 32-bit x86 has not been a realistic target for years. arm64 +// is listed first, as the default build (see the Makefile); the order is for the +// reader only, the builds run concurrently and the checksums are sorted. var builds = map[string][]string{ - "darwin": {"amd64", "arm64"}, - "linux": {"amd64", "arm64"}, + "darwin": {"arm64", "amd64"}, + "linux": {"arm64", "amd64"}, "windows": {"amd64"}, }