Skip to content

Commit a958cdc

Browse files
Swimburgerclaude
andcommitted
chore: add actionlint, resolve-cli tests, fix shell quoting, enable direnv
- Add actionlint to CI and devbox for static linting of action YAML files - Add test workflow for resolve-cli (auto/latest/specific version matrix) - Fix shell quoting in sync-openapi: pass inputs via env vars to avoid breakage with JSON-formatted sources containing double quotes - Add resolve-cli README per CONTRIBUTING.md requirements - Pin pnpm via corepack (packageManager field) instead of devbox package - Enable direnv integration via .envrc Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 5be7a10 commit a958cdc

8 files changed

Lines changed: 385 additions & 12 deletions

File tree

.envrc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/bin/bash
2+
3+
# Automatically sets up your devbox environment whenever you cd into this
4+
# directory via our direnv integration:
5+
6+
eval "$(devbox generate direnv --print-envrc)"
7+
8+
# check out https://www.jetify.com/docs/devbox/ide_configuration/direnv/
9+
# for more details

.github/workflows/ci.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,18 @@ concurrency:
1111
cancel-in-progress: true
1212

1313
jobs:
14+
actionlint:
15+
name: Lint GitHub Actions
16+
runs-on: ubuntu-latest
17+
steps:
18+
- name: Checkout
19+
uses: actions/checkout@v4
20+
21+
- name: Run actionlint
22+
uses: raven-actions/actionlint@v2
23+
with:
24+
matcher: true
25+
1426
ci:
1527
name: Test, Typecheck & Lint
1628
runs-on: ubuntu-latest
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
name: Test resolve-cli
2+
3+
on:
4+
pull_request:
5+
branches: [main]
6+
workflow_dispatch:
7+
8+
concurrency:
9+
group: ${{ github.workflow }}-${{ github.ref }}
10+
cancel-in-progress: true
11+
12+
jobs:
13+
test-resolve-cli:
14+
name: "resolve-cli (${{ matrix.version }})"
15+
runs-on: ubuntu-latest
16+
strategy:
17+
fail-fast: false
18+
matrix:
19+
include:
20+
- version: auto
21+
expected-fern-cmd: "npx --yes fern-api@latest"
22+
expect-no-version-redirection: "false"
23+
- version: latest
24+
expected-fern-cmd: "npx --yes fern-api@latest"
25+
expect-no-version-redirection: "true"
26+
- version: "0.46.10"
27+
expected-fern-cmd: "npx --yes fern-api@0.46.10"
28+
expect-no-version-redirection: "true"
29+
steps:
30+
- name: Checkout
31+
uses: actions/checkout@v4
32+
33+
- name: Resolve CLI
34+
id: cli
35+
uses: ./actions/resolve-cli
36+
with:
37+
version: ${{ matrix.version }}
38+
39+
- name: Assert fern-cmd
40+
shell: bash
41+
run: |
42+
actual="${{ steps.cli.outputs.fern-cmd }}"
43+
expected="${{ matrix.expected-fern-cmd }}"
44+
if [[ "$actual" != "$expected" ]]; then
45+
echo "::error::fern-cmd mismatch: expected '$expected', got '$actual'"
46+
exit 1
47+
fi
48+
echo "fern-cmd OK: $actual"
49+
50+
- name: Assert FERN_NO_VERSION_REDIRECTION
51+
shell: bash
52+
run: |
53+
expect="${{ matrix.expect-no-version-redirection }}"
54+
if [[ "$expect" == "true" ]]; then
55+
if [[ -z "${FERN_NO_VERSION_REDIRECTION:-}" ]]; then
56+
echo "::error::FERN_NO_VERSION_REDIRECTION should be set but is not"
57+
exit 1
58+
fi
59+
echo "FERN_NO_VERSION_REDIRECTION OK: set to '${FERN_NO_VERSION_REDIRECTION}'"
60+
else
61+
if [[ -n "${FERN_NO_VERSION_REDIRECTION:-}" ]]; then
62+
echo "::error::FERN_NO_VERSION_REDIRECTION should NOT be set but is '${FERN_NO_VERSION_REDIRECTION}'"
63+
exit 1
64+
fi
65+
echo "FERN_NO_VERSION_REDIRECTION OK: not set"
66+
fi
67+
68+
- name: Assert FERN_RUN_ID
69+
shell: bash
70+
run: |
71+
if [[ -z "${FERN_RUN_ID:-}" ]]; then
72+
echo "::error::FERN_RUN_ID is not set"
73+
exit 1
74+
fi
75+
echo "FERN_RUN_ID OK: ${FERN_RUN_ID}"

actions/resolve-cli/README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# resolve-cli
2+
3+
A shared composite action that resolves the Fern CLI command based on a requested version. Used internally by other Fern actions to centralize CLI version resolution logic.
4+
5+
## Inputs
6+
7+
| Input | Description | Default |
8+
|-------|-------------|---------|
9+
| `version` | `auto` respects `fern.config.json`, `latest` uses the newest release, `inherit` uses whatever CLI is on PATH, or a specific version/npm tag (e.g. `0.15.0`, `beta`). | `auto` |
10+
11+
## Outputs
12+
13+
| Output | Description |
14+
|--------|-------------|
15+
| `fern-cmd` | The resolved command to invoke the Fern CLI (e.g. `npx --yes fern-api@latest` or `fern`). |
16+
17+
## Usage
18+
19+
```yaml
20+
steps:
21+
- uses: fern-api/actions/resolve-cli@main
22+
id: cli
23+
with:
24+
version: "latest"
25+
26+
- run: ${{ steps.cli.outputs.fern-cmd }} generate
27+
```
28+
29+
## Version resolution
30+
31+
| `version` value | Behavior |
32+
|-----------------|----------|
33+
| `auto` | Installs latest via `npx`, lets the CLI resolve from `fern.config.json` at runtime. |
34+
| `latest` | Installs latest via `npx` with `FERN_NO_VERSION_REDIRECTION=true`. |
35+
| `inherit` | Uses bare `fern` from PATH with `FERN_NO_VERSION_REDIRECTION=true`. Fails if `fern` is not found. |
36+
| `0.15.0` / `beta` / any tag | Installs that version via `npx` with `FERN_NO_VERSION_REDIRECTION=true`. |

actions/sync-openapi/action.yml

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,24 +42,34 @@ runs:
4242
shell: bash
4343
env:
4444
FERN_TOKEN: ${{ inputs.token }}
45+
TOKEN: ${{ inputs.token }}
46+
BRANCH: ${{ inputs.branch }}
47+
AUTO_MERGE: ${{ inputs.auto_merge }}
4548
run: |
46-
${{ steps.cli.outputs.fern-cmd }} gha pull-spec \
47-
--token "${{ inputs.token }}" \
48-
${{ inputs.branch != '' && format('--branch "{0}"', inputs.branch) || '' }} \
49-
${{ inputs.auto_merge == 'true' && '--auto-merge' || '' }}
49+
ARGS=()
50+
ARGS+=(--token "$TOKEN")
51+
[ -n "$BRANCH" ] && ARGS+=(--branch "$BRANCH")
52+
[ "$AUTO_MERGE" = "true" ] && ARGS+=(--auto-merge)
53+
${{ steps.cli.outputs.fern-cmd }} gha pull-spec "${ARGS[@]}"
5054
5155
- name: Sync files to target repository
5256
if: inputs.update_from_source != 'true'
5357
shell: bash
5458
env:
5559
FERN_TOKEN: ${{ inputs.token }}
60+
REPOSITORY: ${{ inputs.repository }}
61+
SOURCES: ${{ inputs.sources }}
62+
TOKEN: ${{ inputs.token }}
63+
BRANCH: ${{ inputs.branch }}
64+
AUTO_MERGE: ${{ inputs.auto_merge }}
5665
run: |
57-
${{ steps.cli.outputs.fern-cmd }} gha sync-specs \
58-
--repository "${{ inputs.repository }}" \
59-
--sources "${{ inputs.sources }}" \
60-
--token "${{ inputs.token }}" \
61-
${{ inputs.branch != '' && format('--branch "{0}"', inputs.branch) || '' }} \
62-
${{ inputs.auto_merge == 'true' && '--auto-merge' || '' }}
66+
ARGS=()
67+
ARGS+=(--repository "$REPOSITORY")
68+
ARGS+=(--sources "$SOURCES")
69+
ARGS+=(--token "$TOKEN")
70+
[ -n "$BRANCH" ] && ARGS+=(--branch "$BRANCH")
71+
[ "$AUTO_MERGE" = "true" ] && ARGS+=(--auto-merge)
72+
${{ steps.cli.outputs.fern-cmd }} gha sync-specs "${ARGS[@]}"
6373
6474
branding:
6575
icon: "refresh-cw"

devbox.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
{
22
"$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.16.0/.schema/devbox.schema.json",
3-
"packages": ["nodejs@20", "pnpm@10.30.1", "git@latest", "gh@latest"],
3+
"packages": ["nodejs@20", "git@latest", "gh@latest", "actionlint@1.7.10"],
4+
"env": {
5+
"DEVBOX_COREPACK_ENABLED": "true"
6+
},
47
"shell": {
58
"init_hook": [
69
"printf '\\033]0;%s\\007' 'fern-github-actions (devbox)'",
@@ -13,7 +16,8 @@
1316
"install": "pnpm install",
1417
"build": "pnpm build",
1518
"test": "pnpm test",
16-
"check": "pnpm check"
19+
"check": "pnpm check",
20+
"lint-actions": "actionlint"
1721
}
1822
}
1923
}

0 commit comments

Comments
 (0)