Skip to content

Latest commit

 

History

History
193 lines (140 loc) · 12.2 KB

File metadata and controls

193 lines (140 loc) · 12.2 KB
title CLI
description Validate and migrate smartcloud configs from the command line.

The smartcloud command runs the same code as the action on your own machine. Use it to check a config before you push it, convert a v1 config, see what a run would do without doing it, and find out why a repository is not set up right. Nothing it does writes to GitHub.

Command Use it to Needs a token
validate Check a config and every preset it extends. Only for extends
migrate Convert a v1 .github/config.json to v2 YAML. No
check-commit Check a commit message for DCO sign-off and AI attribution, as a git hook. No
dry-run Run every feature against a real pull request, issue or event, writing nothing. Yes
plan settings List the repository settings the config would apply. Yes
sync Render the files the sync feature would write into a local folder. Yes
doctor Check the token, config, presets, private actions, secrets and variables. Yes

Install

You need Node 24 or later.

From the first v2 release, the CLI and the [MCP server](/mcp-server) are published together as `@resnovas/smartcloud`:
```sh
npx @resnovas/smartcloud --help
# or install it once
npm install --global @resnovas/smartcloud
smartcloud --help
```
Until then, or to try unreleased changes, build it from this repository:
```sh
git clone https://github.com/Resnovas/smartcloud.git
cd smartcloud
pnpm install
pnpm nx run @resnovas/smartcloud:build
node apps/cli/dist/main.js --help
```

Inside the checkout, `pnpm run cli <command>` does the same.

The examples below write smartcloud for whichever you use. smartcloud --version prints the version, and smartcloud <command> --help lists a command's options.

A command that fails prints one line starting smartcloud: on stderr and exits with code 1. Any other result exits with code 0.

validate

smartcloud validate [path]

Checks a config and every preset it extends, merges them under the locked preset rules, and prints where the config was built from and any migration warnings.

Without a path, it uses the first of .github/smartcloud.yml, .github/smartcloud.yaml and .github/config.json in the current directory.

$ smartcloud validate
.github/smartcloud.yml is a valid smartcloud config.
Built from: Resnovas/.github/smartcloud/house.yml@main, .github/smartcloud.yml

Validation is strict: an unknown key or invalid value in the config or any preset is an error, where a run only drops it with a warning. A config that fails prints one line starting smartcloud: and exits with code 1.

migrate

smartcloud migrate [input] [--out <file>]

Converts a v1 JSON config (default .github/config.json) to v2 YAML, and prints a warning for every v1 key it does not carry over. The output starts with a schema hint for editors, and is proven to decode before it is written.

Option Meaning
--out, -o Write the YAML to this file instead of printing it.

A v2 file given to migrate is rewritten unchanged. See Migrating from v1 for worked examples.

check-commit

smartcloud check-commit <file> [--author-name <name> --author-email <email>] [--config <file>]

Checks a commit message against the DCO sign-off and AI attribution rules before the commit exists, and exits with code 1 when any rule is broken. The author defaults to git's own, and the config to the repository's in the working directory, or smartcloud's defaults when there is none. Comment lines are ignored, as git ignores them.

Use it as a git commit-msg hook, so a commit that would fail the pull request check is stopped locally:

#!/bin/sh
exec npx --yes @resnovas/smartcloud check-commit "$1"

dry-run

smartcloud dry-run --repo <owner/name> (--pr <n> | --issue <n> | --event <event>) [--config <file>] [--features <a,b>]

Runs every feature against a real pull request, issue or repository event, through the dry-run layer. It reads GitHub as the action would, then prints the job summary and every write the run would make. It never writes.

Option Meaning
--repo The repository, as owner/name.
--pr, --issue Simulate this pull request or issue, built from its current state on GitHub.
--event Simulate schedule, push or workflow_dispatch.
--config Use this local config file instead of the repository's own config on its default branch.
--features Only these features, comma separated. An empty list, such as --features ,, runs every feature.

Give exactly one of --pr, --issue or --event.

# What would smartcloud do on pull request 42, with the config I am editing?
smartcloud dry-run --repo my-org/my-repo --pr 42 --config .github/smartcloud.yml

# What would the daily sweep do, stale and lock only?
smartcloud dry-run --repo my-org/my-repo --event schedule --features stale,lock

plan settings

smartcloud plan settings --repo <owner/name> [--config <file>]

Prints every repository settings step the config would apply, with its request, without applying any of them. Use it before merging a change to the settings section, since those steps change the repository for everyone.

smartcloud plan settings --repo my-org/my-repo --config .github/smartcloud.yml

It reads only the repository itself, so any token that can read the repository works. A config without a settings section prints no steps. When a run would ignore part of the settings section, such as a merge queue method that conflicts with the rest of the ruleset, the plan lists it after the steps under "Ignored, so not applied", with the reason.

sync

smartcloud sync --repo <owner/name> --out <dir> [--config <file>]
smartcloud sync --repo my-org/my-repo --out /tmp/sync-preview

Renders the files the sync feature would write to the repository into a local directory, with each file's status (added, updated, made executable or unchanged), and lists any conflicts. Nothing is sent to GitHub. A config without a sync section fails with the config has no sync section. Every file is checked before any is written: one that would land outside the directory, or be written through a symlink inside it, stops the command with nothing written.

doctor

smartcloud doctor --repo <owner/name> [--config <file>]

Checks what smartcloud needs to run on a repository, with the token the CLI finds, and prints one line per check. It exits with code 1 when any check fails. Nothing is written.

Check Fails or warns when
token, token scopes A classic or OAuth token lacks the repo scope (fails) or the workflow scope (warns).
check runs The token is a personal or OAuth token, which GitHub never lets create check runs, or a workflow passes a secret to smartcloud as its token (warns: if that secret is a personal access token, the smartcloud check fails). Use a GitHub App token or the workflow token.
repository The token cannot read the repository (fails, and the remaining checks are skipped), or is not an admin, so the settings feature cannot run (warns).
config, presets The config, or any preset it extends, cannot be read or is invalid (fails). A private preset in another repository is noted, because runs with the workflow token skip it.
actions access A workflow uses an action or reusable workflow from a private repository whose Actions access (Settings > Actions > General > Access) does not allow it (fails). Reading the access level needs admin access to that repository; without it, the check warns.
workflows The workflow files under .github/workflows cannot be read (warns), so the checks that read them are skipped.
secrets, variables A workflow reads a secret or variable that the repository, its organisation and its environments do not have (fails). Listing them needs admin access; when a list cannot be read, the check warns instead.

Run it with your own token to check the repository, or with the token a workflow passes to smartcloud to check that token:

$ smartcloud doctor --repo Resnovas/example
smartcloud doctor for Resnovas/example:
ok      token: an OAuth token, such as the GitHub CLI's with scopes: repo, workflow, read:org
warning check runs: this token cannot create check runs, so the smartcloud check fails in a workflow that passes it; ...
ok      repository: the token is an admin of Resnovas/example, so every feature can run
ok      config: the config and its 1 preset(s) resolve: Resnovas/private-presets/smartcloud/house.yml@main, .github/smartcloud.yml
ok      presets: Resnovas/private-presets is private: runs with the workflow token, such as pull requests from forks and Dependabot, skip its presets
ok      workflows: read 4 workflow file(s)
ok      actions access: public, so usable from any workflow: actions/checkout, actions/setup-node
FAIL    actions access: Resnovas/private-presets is private and its Actions access is none, so .github/workflows/house-graphify.yml cannot use its actions or reusable workflows; ...
FAIL    secrets: missing POSTHOG_CLI_TOKEN (read by .github/workflows/house-release.yml); ...
ok      variables: every variable the workflows read exists: RESNOVAS_BOT_APP_ID
2 failure(s), 1 warning(s).

Workflows are read line by line rather than parsed: every uses: of another repository and every secrets.NAME or vars.NAME outside a comment line counts, including one guarded by a condition.

Tokens

dry-run, plan settings, sync and doctor always read GitHub. validate needs a token only to read presets named in extends, so validating a config without presets works offline. When it does need one, it uses GITHUB_TOKEN if set, and otherwise the token of the signed-in GitHub CLI (gh auth token). The token is never printed.