Skip to content

Importing local rules

How to upload locally developed .cgr rules to the portal using codecharter push.

When you develop rules locally — for example with the VS Code extension or directly in a text editor — you can upload them to the portal with codecharter push. The command scans a directory for .cgr files, uploads them as rule drafts, and creates a profile draft in the portal without touching the currently published version. If a rule or the profile already has an open draft in the portal, the push stops with a conflict instead of overwriting it.

Prerequisites

You need:

  • A CodeCharter CLI that includes the push command — run codecharter --version to check. If you need to upgrade, see Downloads.
  • A valid API key passed via the required --api-key option (you can keep the key in an environment variable and pass it on the command line, as in the examples below)
  • One .cgr file per rule, optionally a .spec.md file with the same base name next to it

Directory layout

codecharter push operates on a directory and scans it recursively for .cgr files:

rules/
  no-async-void.cgr
  no-async-void.spec.md
  max-method-length.cgr

Canonical usage

codecharter push ./rules \
  --profile my-team-rules \
  --version 1.0.0 \
  --portal-url https://codecharter.tools \
  --api-key $CODECHARTER_API_KEY

This scans ./rules recursively for .cgr files. Each rule's slug is derived from the filename (without the .cgr extension), so no-async-void.cgr becomes the slug no-async-void. A sibling .spec.md with the same base name is uploaded automatically. The run creates the profile draft [email protected] from those rules; if the profile already has an open draft, the push fails with a conflict so it cannot overwrite work in progress.

On success the CLI prints a summary line you can verify against:

Pushed 2 rule(s); profile draft '[email protected]' created.

There is no rule: or severity: declaration block — the slug comes from the filename, and the severity comes from the @severity directive inside the rule file (default: warn if the directive is absent). codecharter push uploads the file content as-is; the directive takes effect when the rule is loaded.

Dry run

codecharter push ./rules \
  --profile my-team-rules \
  --version 1.0.0 \
  --portal-url https://codecharter.tools \
  --api-key $CODECHARTER_API_KEY \
  --dry-run

--dry-run lists the rules and the profile draft that would be pushed, without uploading anything. Useful to verify the plan before opening real drafts.

Options

Option Required Description
--profile <slug> yes The profile slug to create or update.
--version <semver> yes The semantic version for the profile draft (e.g. 1.0.0).
--portal-url <url> yes URL of the CodeCharter portal.
--api-key <key> yes API key used to authenticate against the portal.
--dry-run no Show planned actions without uploading.

Exit codes

Code Meaning
0 All drafts created successfully (or dry run completed).
1 A rule or the profile already has a conflicting draft.
2 Usage error, I/O error, or network error.

After the push

After a successful push the rule appears in the portal under /rules with the Draft badge. From there you can:

  • run the spec in the portal (Run specs)
  • use the live trial to test the rule against real C# code
  • publish a new version (Publish)

A push never publishes on its own — that remains a deliberate manual step in the portal.

If a pushed rule has no published version yet, the profile draft references the rule draft and the CLI warns:

warning: rule 'no-async-void' has no published version yet; profile references the draft.

Common errors

Conflicting draft

error: Rule 'no-async-void' already has a draft. Discard or publish it first.
error: Profile 'my-team-rules' already has a draft. Discard or publish it first.

A rule or the profile already has an open draft in the portal. Discard or publish that draft in the portal, then push again. The command exits with code 1.

API key missing

error: --api-key is required.

Pass the key with --api-key. The command exits with code 2.

No rule files found

error: no .cgr files found in './rules'.

The directory does not contain any .cgr files (the scan is recursive). Check the path you passed. The command exits with code 2.

Portal rejects the request

error: portal returned 401 Unauthorized for rule 'no-async-void'.

The portal refused the upload. Check that the API key is valid and not expired, and that --portal-url points to the right portal. The command exits with code 2.

Further reading