Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
504865e
feat: install the CLI and exchange the job's OIDC token
khvn26 Aug 18, 2026
5946040
refactor: delegate installation to the CLI's own installers
khvn26 Aug 18, 2026
4864241
refactor: drop the action's outputs
khvn26 Aug 18, 2026
ca672a5
refactor: collapse the platform branches and drop the unread token type
khvn26 Aug 18, 2026
f6bee56
refactor: stop pre-checking for curl and wget
khvn26 Aug 18, 2026
236cb00
refactor: look failure hints up in a table
khvn26 Aug 18, 2026
85d7cbc
refactor: inline the version helpers into resolveVersion
khvn26 Aug 18, 2026
1275a2d
test: read a real event file instead of injecting a reader
khvn26 Aug 18, 2026
d0db1b8
refactor: order each module public-first and high-level-first
khvn26 Aug 18, 2026
b724eb0
fix: show the error body whatever its content type
khvn26 Aug 18, 2026
f409361
refactor: find the folded credential name in one expression
khvn26 Aug 18, 2026
1be14d4
style: drop a blank line from an import list
khvn26 Aug 18, 2026
5b8aebd
refactor: inline the api-url normalisation into its only caller
khvn26 Aug 18, 2026
3afe754
refactor: normalise api-url with the URL parser
khvn26 Aug 18, 2026
e9123ad
refactor: read GITHUB_TOKEN where it is used
khvn26 Aug 18, 2026
2b14fa1
refactor: one error for a release response we cannot read
khvn26 Aug 18, 2026
9f75a39
fix: show the release response body when it cannot be read
khvn26 Aug 18, 2026
656147b
refactor: let the installer choose the latest release
khvn26 Aug 18, 2026
aa07fd1
feat: resolve an unpinned version with the installer's dry run
khvn26 Aug 18, 2026
4b1588f
fix: degrade to an uncached install when the dry run says nothing
khvn26 Aug 18, 2026
7195aac
refactor: inline the dry-run parse into installCli
khvn26 Aug 18, 2026
570516f
feat: fall back to the installed binary for the cache key
khvn26 Aug 18, 2026
a48eb3b
refactor: take the version straight from the binary's output
khvn26 Aug 18, 2026
fe69ab5
refactor: one truthiness test for the resolved version
khvn26 Aug 18, 2026
2396f60
refactor: name the installer scripts with a literal union
khvn26 Aug 18, 2026
93c6ead
refactor: split the entrypoint from the action logic
khvn26 Aug 18, 2026
b3eaa99
refactor: one throw for a response that is not a 200
khvn26 Aug 18, 2026
fd43813
improve docs
khvn26 Aug 18, 2026
dd357b9
chore: pre-commit, security-only renovate, release-please, PR tests
khvn26 Aug 18, 2026
01ce478
chore: pin workflow actions to commit SHAs
khvn26 Aug 18, 2026
b501213
chore: drop the CI test workflow
khvn26 Aug 18, 2026
e0f39f3
fix: name the version that ships the exchange endpoint
khvn26 Aug 18, 2026
229ecac
improve docs
khvn26 Aug 18, 2026
610d53c
chore: empty commit to trigger CI
khvn26 Aug 18, 2026
41ea715
chore: skip the npm hooks on pre-commit.ci
khvn26 Aug 18, 2026
64c1b59
ci: replace CI-duplicating pre-commit hooks with linting hooks
khvn26 Aug 19, 2026
7a998a7
docs: clarify the audience input default
khvn26 Aug 19, 2026
0d93bef
docs: show a conventional bring-your-own-key example
khvn26 Aug 19, 2026
cd8cc94
docs: stop enumerating the exported environment variables
khvn26 Aug 19, 2026
ee4a8c0
ci: keep the README usage examples on the released major
khvn26 Aug 19, 2026
025d1ad
refactor: split constants out of a renamed credentials module
khvn26 Aug 19, 2026
c1b5161
fix: look up unscoped credentials by their exact name, as the CLI does
khvn26 Aug 19, 2026
7eaf216
docs: describe fetchOk in plain language
khvn26 Aug 19, 2026
8adfee8
refactor: return installer behavior instead of an argument bag
khvn26 Aug 19, 2026
b4ed3d5
refactor: inline the case-insensitive lookup at its only call site
khvn26 Aug 19, 2026
e393d0d
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 19, 2026
467d113
refactor: rename fetchOk to fetchOrThrow
khvn26 Aug 19, 2026
e9658c0
refactor: name the install steps for what they do
khvn26 Aug 19, 2026
d4b6af8
docs: explain scoped and unscoped credential names
khvn26 Aug 19, 2026
77791f0
push major tag so all example snippets actually work
khvn26 Aug 20, 2026
e7dd140
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 20, 2026
cd32a6d
test: cover every exchangeFailureHint mapping and unescape a test name
khvn26 Aug 20, 2026
98c2c6c
test: unit test every exchangeFailureHint status mapping
khvn26 Aug 20, 2026
99b3e89
skip bumping major tag for prereleases
khvn26 Aug 20, 2026
1992dbf
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 20, 2026
eb2f097
test: replace the mock-server exchange tests with a real smoke test
khvn26 Aug 20, 2026
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
29 changes: 29 additions & 0 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Pull request

on: pull_request

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 24
cache: npm
- run: npm ci
- run: npx vitest run

test-e2e:
runs-on: ubuntu-latest
environment: test
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: ./
with:
api-url: https://api-staging.flagsmith.com
- run: flagsmith --version
- run: flagsmith flag list --project "Flagsmith/setup-cli E2E" -e E2E
25 changes: 25 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Update major tag on release

on:
release:
types: [published]

permissions:
contents: write

jobs:
major-tag:
if: ${{ !github.event.release.prerelease }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- id: get-major-tag
run: |
major="v${GITHUB_REF_NAME#v}"; major="v${major%%.*}"
Comment thread
matthewelwell marked this conversation as resolved.
echo "result=$major" >> "$GITHUB_OUTPUT"
- name: Bump ${{ steps.get-major-tag.outputs.result }}
run: |
# Point the floating major tag at this release
# Makes `uses: Flagsmith/setup-cli@v1` work
git tag -f "${{ steps.get-major-tag.outputs.result }}" "$GITHUB_REF_NAME"
git push -f origin "${{ steps.get-major-tag.outputs.result }}"
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules/
lib/
*.tsbuildinfo
27 changes: 27 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
exclude: ^dist/
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
- id: check-yaml
- id: check-json
- id: check-merge-conflict
- id: end-of-file-fixer
- id: trailing-whitespace

- repo: https://github.com/rbubley/mirrors-prettier
rev: v3.9.6
hooks:
- id: prettier
types_or: [ts, json, yaml, markdown]

- repo: https://github.com/rhysd/actionlint
rev: v1.7.12
hooks:
- id: actionlint

- repo: https://github.com/python-jsonschema/check-jsonschema
rev: 0.38.0
hooks:
- id: check-github-workflows
- id: check-renovate
4 changes: 4 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"semi": false,
"singleQuote": true
}
3 changes: 3 additions & 0 deletions .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
".": "1.0.0"
}
71 changes: 69 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,69 @@
# setup-cli
鈻讹笍 GitHub Action to download and install the Flagsmith CLI
# `Flagsmith/setup-cli`

Install the [Flagsmith CLI](https://github.com/Flagsmith/flagsmith-cli) in a GitHub Actions job, and authenticate it without storing a secret.

## Usage

<!-- x-release-please-start-major -->

```yaml
jobs:
flagsmith:
runs-on: ubuntu-latest
permissions:
id-token: write # required for the token exchange
contents: read
steps:
- uses: Flagsmith/setup-cli@v1
- run: flagsmith auth status
```

<!-- x-release-please-end -->

Or, with a static key:

<!-- x-release-please-start-major -->
Comment thread
khvn26 marked this conversation as resolved.

```yaml
jobs:
flagsmith:
runs-on: ubuntu-latest
env:
FLAGSMITH_API_KEY: ${{ secrets.FLAGSMITH_API_KEY }}
steps:
# Installs the CLI and skips the token exchange:
- uses: Flagsmith/setup-cli@v1
- run: flagsmith flags list # uses your key
```

<!-- x-release-please-end -->

## Inputs

| Input | Default | Description |
| ------------- | --------------------------- | ------------------------------------------------------------------------------------------------------ |
| `api-url` | `https://api.flagsmith.com` | Flagsmith API base URL. Set this for self-hosted instances. |
| `audience` | `https://github.com/OWNER` | The `aud` claim to request. Only set this if your Flagsmith trust relationship uses a custom audience. |
| `cli-version` | `latest` | CLI version to install, e.g. `v2.0.0`. |

## When the action skips authentication

The action always installs the CLI, but may skip authentication if:

- the run is a pull request from a fork.
- the job has no `id-token: write` permission.
- the job already carries a credential the CLI would use for this `api-url` (`FLAGSMITH_API_KEY` or `FLAGSMITH_ACCESS_TOKEN`, scoped to provided `api-url`).

## After the action runs

The API URL and the exchanged access token are exported to the job environment, where the CLI picks them up.

The CLI binary is added to `PATH` via `GITHUB_PATH`, and cached in the runner tool cache by version and architecture.

## Development

```sh
npm ci
npm test # unit tests
npm run all # typecheck, test, and rebuild dist/
```
31 changes: 31 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Setup Flagsmith CLI
description: >-
Install the Flagsmith CLI and, when the job has an OIDC identity, exchange it
for a short-lived Flagsmith access token.
author: Flagsmith
branding:
icon: flag
color: purple

inputs:
api-url:
description: Flagsmith API base URL.
required: false
default: https://api.flagsmith.com
audience:
description: >-
The `aud` claim to request for the GitHub OIDC token. Defaults to
GitHub's own default, https://github.com/OWNER. Only set this if your
Flagsmith trust relationship uses a custom audience.
required: false
default: ''
cli-version:
description: >-
Version of the CLI to install, e.g. `v2.0.0`. Defaults to the latest
release.
required: false
default: latest

runs:
using: node24
main: dist/index.cjs
Loading