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
50 changes: 48 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ jobs:
go-version: ["1.26"]

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7

- name: Set up Go
uses: actions/setup-go@v5
uses: actions/setup-go@v7
with:
go-version: ${{ matrix.go-version }}

Expand All @@ -38,3 +38,49 @@ jobs:

- name: Test
run: make test

packaging:
name: Packaging config
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0

- name: Set up Go
uses: actions/setup-go@v7
with:
go-version: "1.26"

# Catches deprecated or invalid goreleaser properties on a PR, rather than
# when a tag push turns them into a failed release.
- name: Validate goreleaser config
uses: goreleaser/goreleaser-action@v7
with:
version: "~> v2"
args: check

# Proves all four release targets still cross-compile without cgo.
- name: Build all release targets
uses: goreleaser/goreleaser-action@v7
with:
version: "~> v2"
args: build --snapshot --clean

nix:
name: Nix flake
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7

- uses: cachix/install-nix-action@v31

# Guards vendorHash, which goes stale whenever go.mod or go.sum changes.
# Nothing else would catch it: the Go build is unaffected, so the flake
# would stay broken until someone ran `nix run`. This also runs the test
# suite inside the Nix sandbox, which has no network.
- name: Build the flake
run: nix build .#mcli

- name: Smoke-test the built binary
run: ./result/bin/mcli version
99 changes: 22 additions & 77 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,91 +5,36 @@ on:
tags:
- 'v*'

jobs:
build:
name: Build ${{ matrix.goos }}/${{ matrix.goarch }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- os: ubuntu-latest
goos: linux
goarch: amd64
cgo_enabled: "0"
- os: ubuntu-latest
goos: linux
goarch: arm64
cgo_enabled: "0"
- os: macos-latest
goos: darwin
goarch: arm64
cgo_enabled: "1"
permissions:
contents: write

jobs:
goreleaser:
name: Build and publish
# Every target cross-compiles from this one runner because the build needs no
# cgo. The previous matrix required a macOS runner for darwin, which is what
# made the Intel build queue indefinitely (no macos-13 runner) and left tags
# unpublished.
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
with:
# goreleaser derives the version and changelog from tags.
fetch-depth: 0

- name: Set up Go
uses: actions/setup-go@v5
uses: actions/setup-go@v7
with:
go-version: "1.26"

- name: Build
env:
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
CGO_ENABLED: ${{ matrix.cgo_enabled }}
run: |
VERSION=$(git describe --tags --always)
BINARY=mcli-${{ matrix.goos }}-${{ matrix.goarch }}
go build \
-ldflags "-X github.com/mondaycom/mcli/internal/cli.version=${VERSION}" \
-o "${BINARY}" \
./cmd/mcli

- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: mcli-${{ matrix.goos }}-${{ matrix.goarch }}
path: mcli-${{ matrix.goos }}-${{ matrix.goarch }}
if-no-files-found: error

release:
name: Create Release
needs: build
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Release
uses: goreleaser/goreleaser-action@v7
with:
fetch-depth: 0

- name: Download artifacts
uses: actions/download-artifact@v4
with:
path: dist/
merge-multiple: true

# Run inside dist/ so the recorded names are flat (mcli-linux-amd64, not
# dist/mcli-linux-amd64). Users download the assets side by side, where a
# dist/ prefix makes `sha256sum -c checksums.txt` fail to find every file —
# and it exits 0 when no file is found, so a scripted install that thinks it
# verifies checksums would silently verify nothing.
- name: Checksums
working-directory: dist
run: sha256sum mcli-* > checksums.txt

- name: Create release
version: "~> v2"
args: release --clean
env:
GH_TOKEN: ${{ github.token }}
TAG: ${{ github.ref_name }}
run: |
gh release create "$TAG" \
--title "$TAG" \
--generate-notes \
dist/mcli-linux-amd64 \
dist/mcli-linux-arm64 \
dist/mcli-darwin-arm64 \
dist/checksums.txt
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# PAT with contents:write on mondaycom/homebrew-tap. The per-run
# GITHUB_TOKEN is scoped to this repository and cannot push the cask
# to another one.
HOMEBREW_TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Build artifacts
/bin/
/dist/
# `nix build` output symlinks
/result
/result-*
/mcli
/mcli.exe

Expand Down
113 changes: 113 additions & 0 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
version: 2

project_name: mcli

before:
hooks:
- go mod download

builds:
- id: mcli
main: ./cmd/mcli
binary: mcli
# CGO is not needed on any target. The darwin keychain backend
# (zalando/go-keyring) shells out to /usr/bin/security via os/exec and
# contains no cgo at all, verified by a real set/get/delete round-trip from a
# CGO_ENABLED=0 binary. That is what lets every target cross-compile from one
# Linux runner, Intel macOS included.
env:
- CGO_ENABLED=0
goos:
- linux
- darwin
goarch:
- amd64
- arm64
ldflags:
- -s -w -X github.com/mondaycom/mcli/internal/cli.version={{ .Version }}
# Reproducible builds: stamp binaries with the commit time rather than the
# build time, so rebuilding a tag produces identical bytes.
mod_timestamp: "{{ .CommitTimestamp }}"

archives:
# Tarballs are what the Homebrew formula consumes, and they carry the LICENSE
# alongside the binary.
- id: archive
ids:
- mcli
formats:
- tar.gz
name_template: "mcli_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
files:
- LICENSE
- README.md
# Bare binaries under the same names v0.8.0 published, so existing
# `curl -LO .../mcli-darwin-arm64` instructions keep working.
- id: binary
ids:
- mcli
formats:
- binary
name_template: "mcli-{{ .Os }}-{{ .Arch }}"

checksum:
# Flat names, so `sha256sum -c checksums.txt` works where the assets are
# actually downloaded. goreleaser does this correctly by default; the previous
# hand-rolled step recorded a dist/ prefix that matched nothing and still
# exited 0.
name_template: "checksums.txt"

changelog:
use: github
sort: asc
filters:
exclude:
- "^test:"
- "^chore:"
- "^ci:"
- "Merge pull request"

# Casks, not formulas: goreleaser deprecated `brews` in favour of
# `homebrew_casks`, since what it generated for pre-compiled binaries were
# "hackyish" formulas. The generated cask does declare on_linux URLs, but
# Homebrew only supports casks on macOS, so Linux users install via Nix,
# `go install`, or the tarballs above.
homebrew_casks:
- name: mcli
# Build the cask from the tarball, not the bare binary.
ids:
- archive
# `binaries` defaults to the cask name (mcli), so it is left unset.
repository:
owner: mondaycom
name: homebrew-tap
# Needs a PAT with `contents: write` on mondaycom/homebrew-tap: the
# per-run GITHUB_TOKEN is scoped to this repo only and cannot push there.
token: "{{ .Env.HOMEBREW_TAP_TOKEN }}"
homepage: "https://github.com/mondaycom/mcli"
description: "Command-line interface for monday.com's GraphQL API, built for LLM agents"
hooks:
post:
# These binaries are not signed or notarized, and Homebrew quarantines
# cask downloads, so without this macOS reports "mcli is damaged and
# cannot be opened" on first run. The proper fix is an Apple Developer
# signing identity plus notarization; until then, strip the attribute.
install: |
if OS.mac?
system_command "/usr/bin/xattr", args: ["-dr", "com.apple.quarantine", "#{staged_path}/mcli"]
end

release:
prerelease: auto
footer: |
## Install

```sh
brew install mondaycom/tap/mcli
```

Verify a manual download:

```sh
sha256sum -c checksums.txt
```
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,26 @@ A command-line interface for monday.com's GraphQL API. Single static binary, str
## Install

```sh
# Homebrew (macOS)
brew install mondaycom/tap/mcli

# Nix
nix profile install github:mondaycom/mcli

# From source
go install github.com/mondaycom/mcli/cmd/mcli@latest

# Or build locally
make build # → bin/mcli
```

Or download a binary from the [latest release](https://github.com/mondaycom/mcli/releases/latest)
and verify it against the published manifest:

```sh
sha256sum -c checksums.txt
```

## Quick Start

```sh
Expand Down
27 changes: 27 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading