@smoothbricks/cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +289 -0
- package/bin/smoo +4 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +141 -0
- package/dist/github-ci/index.d.ts +11 -0
- package/dist/github-ci/index.d.ts.map +1 -0
- package/dist/github-ci/index.js +174 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -0
- package/dist/lib/json.d.ts +13 -0
- package/dist/lib/json.d.ts.map +1 -0
- package/dist/lib/json.js +57 -0
- package/dist/lib/run.d.ts +5 -0
- package/dist/lib/run.d.ts.map +1 -0
- package/dist/lib/run.js +64 -0
- package/dist/lib/workspace.d.ts +23 -0
- package/dist/lib/workspace.d.ts.map +1 -0
- package/dist/lib/workspace.js +101 -0
- package/dist/monorepo/commit-msg.d.ts +2 -0
- package/dist/monorepo/commit-msg.d.ts.map +1 -0
- package/dist/monorepo/commit-msg.js +34 -0
- package/dist/monorepo/git-config.d.ts +2 -0
- package/dist/monorepo/git-config.d.ts.map +1 -0
- package/dist/monorepo/git-config.js +37 -0
- package/dist/monorepo/index.d.ts +19 -0
- package/dist/monorepo/index.d.ts.map +1 -0
- package/dist/monorepo/index.js +59 -0
- package/dist/monorepo/lockfile.d.ts +2 -0
- package/dist/monorepo/lockfile.d.ts.map +1 -0
- package/dist/monorepo/lockfile.js +34 -0
- package/dist/monorepo/managed-files.d.ts +8 -0
- package/dist/monorepo/managed-files.d.ts.map +1 -0
- package/dist/monorepo/managed-files.js +130 -0
- package/dist/monorepo/nx-sync.d.ts +2 -0
- package/dist/monorepo/nx-sync.d.ts.map +1 -0
- package/dist/monorepo/nx-sync.js +5 -0
- package/dist/monorepo/package-hygiene.d.ts +3 -0
- package/dist/monorepo/package-hygiene.d.ts.map +1 -0
- package/dist/monorepo/package-hygiene.js +12 -0
- package/dist/monorepo/package-policy.d.ts +8 -0
- package/dist/monorepo/package-policy.d.ts.map +1 -0
- package/dist/monorepo/package-policy.js +279 -0
- package/dist/monorepo/packed-package.d.ts +2 -0
- package/dist/monorepo/packed-package.d.ts.map +1 -0
- package/dist/monorepo/packed-package.js +92 -0
- package/dist/monorepo/packs/index.d.ts +10 -0
- package/dist/monorepo/packs/index.d.ts.map +1 -0
- package/dist/monorepo/packs/index.js +87 -0
- package/dist/monorepo/runtime.d.ts +2 -0
- package/dist/monorepo/runtime.d.ts.map +1 -0
- package/dist/monorepo/runtime.js +37 -0
- package/dist/release/index.d.ts +24 -0
- package/dist/release/index.d.ts.map +1 -0
- package/dist/release/index.js +325 -0
- package/managed/raw/.git-format-staged.yml +47 -0
- package/managed/raw/tooling/direnv/github-actions-bootstrap.sh +66 -0
- package/managed/raw/tooling/git-hooks/commit-msg.sh +9 -0
- package/managed/raw/tooling/git-hooks/pre-commit.sh +19 -0
- package/managed/templates/github/actions/cache-nix-devenv/action.yml +79 -0
- package/managed/templates/github/actions/cache-node-modules/action.yml +13 -0
- package/managed/templates/github/actions/cache-nx/action.yml +21 -0
- package/managed/templates/github/actions/save-nix-devenv/action.yml +39 -0
- package/managed/templates/github/actions/setup-devenv/action.yml +63 -0
- package/managed/templates/github/workflows/ci.yml +98 -0
- package/managed/templates/github/workflows/publish.yml +136 -0
- package/package.json +68 -0
- package/src/cli.ts +149 -0
- package/src/github-ci/index.ts +196 -0
- package/src/index.ts +1 -0
- package/src/lib/json.ts +68 -0
- package/src/lib/run.ts +76 -0
- package/src/lib/workspace.ts +125 -0
- package/src/monorepo/commit-msg.ts +35 -0
- package/src/monorepo/git-config.ts +43 -0
- package/src/monorepo/index.ts +78 -0
- package/src/monorepo/lockfile.ts +37 -0
- package/src/monorepo/managed-files.ts +153 -0
- package/src/monorepo/nx-sync.ts +6 -0
- package/src/monorepo/package-hygiene.ts +14 -0
- package/src/monorepo/package-policy.ts +307 -0
- package/src/monorepo/packed-package.ts +101 -0
- package/src/monorepo/packs/index.ts +115 -0
- package/src/monorepo/runtime.ts +41 -0
- package/src/release/index.ts +394 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
name: Setup Nix/devenv
|
|
2
|
+
description: Restore caches and build the SmoothBricks devenv shell after checkout.
|
|
3
|
+
|
|
4
|
+
outputs:
|
|
5
|
+
nix-cache-hit:
|
|
6
|
+
description: Whether the Nix profile/store cache restored from the exact primary key.
|
|
7
|
+
value: ${{ steps.nix-cache.outputs.cache-hit }}
|
|
8
|
+
devenv-cache-hit:
|
|
9
|
+
description: Whether the devenv/direnv cache restored from the exact primary key.
|
|
10
|
+
value: ${{ steps.devenv-cache.outputs.cache-hit }}
|
|
11
|
+
|
|
12
|
+
runs:
|
|
13
|
+
using: composite
|
|
14
|
+
steps:
|
|
15
|
+
# This action is intentionally post-checkout only. Repo-local actions do not
|
|
16
|
+
# exist before actions/checkout has populated the working tree.
|
|
17
|
+
- name: ❄️ Install Nix
|
|
18
|
+
uses: DeterminateSystems/nix-installer-action@v22
|
|
19
|
+
with:
|
|
20
|
+
extra-conf: |
|
|
21
|
+
keep-outputs = true
|
|
22
|
+
keep-derivations = true
|
|
23
|
+
gc-keep-derivations = true
|
|
24
|
+
gc-keep-outputs = true
|
|
25
|
+
|
|
26
|
+
- name: 🧊 Cache Nix profiles and store NAR
|
|
27
|
+
id: nix-cache
|
|
28
|
+
uses: ./.github/actions/cache-nix-devenv
|
|
29
|
+
with:
|
|
30
|
+
segment: nix
|
|
31
|
+
|
|
32
|
+
- name: ♻️ Restore Nix store from NAR
|
|
33
|
+
shell: bash
|
|
34
|
+
working-directory: tooling/direnv
|
|
35
|
+
run: ./github-actions-bootstrap.sh restore-store
|
|
36
|
+
|
|
37
|
+
# Restore direnv state only when the Nix cache key is exact. Partial Nix
|
|
38
|
+
# restores can contain a NAR for a different shell closure, and .direnv
|
|
39
|
+
# points directly at derivations inside that closure.
|
|
40
|
+
- name: 🧊 Cache devenv and direnv
|
|
41
|
+
id: devenv-cache
|
|
42
|
+
if: ${{ steps.nix-cache.outputs.cache-hit == 'true' }}
|
|
43
|
+
uses: ./.github/actions/cache-nix-devenv
|
|
44
|
+
with:
|
|
45
|
+
segment: devenv
|
|
46
|
+
|
|
47
|
+
- name: ⚡ Enable Cachix
|
|
48
|
+
uses: cachix/cachix-action@v17
|
|
49
|
+
with:
|
|
50
|
+
name: devenv
|
|
51
|
+
|
|
52
|
+
- name: 🧰 Install devenv
|
|
53
|
+
shell: bash
|
|
54
|
+
working-directory: tooling/direnv
|
|
55
|
+
run: ./github-actions-bootstrap.sh install-devenv
|
|
56
|
+
|
|
57
|
+
- name: 📦 Cache node_modules
|
|
58
|
+
uses: ./.github/actions/cache-node-modules
|
|
59
|
+
|
|
60
|
+
- name: 🐚 Build devenv shell
|
|
61
|
+
shell: bash
|
|
62
|
+
working-directory: tooling/direnv
|
|
63
|
+
run: ./github-actions-bootstrap.sh build-shell
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
pull_request:
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
actions: read
|
|
9
|
+
contents: read
|
|
10
|
+
statuses: write
|
|
11
|
+
|
|
12
|
+
defaults:
|
|
13
|
+
run:
|
|
14
|
+
working-directory: tooling/direnv
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
main:
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
env:
|
|
20
|
+
NIX_STORE_NAR: ${{ github.workspace }}/nix-store.nar
|
|
21
|
+
GH_TOKEN: ${{ github.token }}
|
|
22
|
+
steps:
|
|
23
|
+
# Step 1: GitHub adds "Set up job" automatically
|
|
24
|
+
# Step 2
|
|
25
|
+
- name: 📥 Checkout
|
|
26
|
+
uses: actions/checkout@v6.0.2
|
|
27
|
+
with:
|
|
28
|
+
filter: blob:none
|
|
29
|
+
fetch-depth: 0
|
|
30
|
+
|
|
31
|
+
# Step 3. Composite action internals do not affect top-level job step
|
|
32
|
+
# anchors; update the nx-smart --step values below if top-level steps move.
|
|
33
|
+
- name: 🧱 Setup Nix/devenv
|
|
34
|
+
id: setup
|
|
35
|
+
uses: ./.github/actions/setup-devenv
|
|
36
|
+
|
|
37
|
+
# --- Nx -----------------------------------------------------------------
|
|
38
|
+
|
|
39
|
+
# Step 4
|
|
40
|
+
# Sets the base and head SHAs required for the nx affected commands
|
|
41
|
+
- name: 🧭 Set Nx SHAs
|
|
42
|
+
uses: nrwl/nx-set-shas@v5.0.1
|
|
43
|
+
with:
|
|
44
|
+
workflow-id: ci.yml
|
|
45
|
+
|
|
46
|
+
# Step 5
|
|
47
|
+
- name: 🧠 Restore Nx cache
|
|
48
|
+
id: nx-cache
|
|
49
|
+
uses: ./.github/actions/cache-nx
|
|
50
|
+
|
|
51
|
+
# Step 6
|
|
52
|
+
- name: 🔨 Build
|
|
53
|
+
run: smoo github-ci nx-smart --target build --name "Build" --step 6
|
|
54
|
+
|
|
55
|
+
# Step 7
|
|
56
|
+
- name: 🔍 Lint
|
|
57
|
+
run: smoo github-ci nx-smart --target lint --name "Lint" --step 7
|
|
58
|
+
|
|
59
|
+
# Step 8
|
|
60
|
+
- name: 🧪 Unit Tests
|
|
61
|
+
run: smoo github-ci nx-smart --target test --name "Unit Tests" --step 8
|
|
62
|
+
|
|
63
|
+
# Step 9
|
|
64
|
+
# Nx's database cache needs artifact files and .nx/workspace-data DB
|
|
65
|
+
# metadata restored together; GitHub Actions cache is only the archive
|
|
66
|
+
# transport. Save runs only after build/lint/test succeed on the default
|
|
67
|
+
# branch, so PRs may restore shared cache but cannot publish it.
|
|
68
|
+
- name: 💾 Save Nx cache
|
|
69
|
+
if:
|
|
70
|
+
${{ github.event_name == 'push' && github.ref == format('refs/heads/{0}',
|
|
71
|
+
github.event.repository.default_branch) && steps.nx-cache.outputs.cache-hit != 'true' }}
|
|
72
|
+
uses: actions/cache/save@v5.0.5
|
|
73
|
+
with:
|
|
74
|
+
path: |
|
|
75
|
+
.nx/cache
|
|
76
|
+
.nx/workspace-data/*.db*
|
|
77
|
+
key: ${{ runner.os }}-nx-db-v1-${{ github.sha }}
|
|
78
|
+
|
|
79
|
+
# Step 10
|
|
80
|
+
- name: 📎 Upload trace DBs
|
|
81
|
+
if: ${{ failure() }}
|
|
82
|
+
uses: actions/upload-artifact@v4
|
|
83
|
+
with:
|
|
84
|
+
name: trace-results-${{ github.run_id }}
|
|
85
|
+
path: packages/*/.trace-results.db
|
|
86
|
+
if-no-files-found: ignore
|
|
87
|
+
retention-days: 14
|
|
88
|
+
include-hidden-files: true
|
|
89
|
+
|
|
90
|
+
# --- Cleanup ------------------------------------------------------------
|
|
91
|
+
|
|
92
|
+
# Step 11
|
|
93
|
+
- name: 🧹 Cleanup and cache Nix/devenv
|
|
94
|
+
if: ${{ always() }}
|
|
95
|
+
uses: ./.github/actions/save-nix-devenv
|
|
96
|
+
with:
|
|
97
|
+
nix-cache-hit: ${{ steps.setup.outputs.nix-cache-hit }}
|
|
98
|
+
devenv-cache-hit: ${{ steps.setup.outputs.devenv-cache-hit }}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
inputs:
|
|
6
|
+
bump:
|
|
7
|
+
type: choice
|
|
8
|
+
description:
|
|
9
|
+
Use auto for conventional commits, or force a semver bump. Prerelease publishes to next; all others publish to
|
|
10
|
+
latest.
|
|
11
|
+
options: [auto, patch, minor, major, prerelease]
|
|
12
|
+
default: auto
|
|
13
|
+
dry_run:
|
|
14
|
+
type: boolean
|
|
15
|
+
description: Run release commands without writing versions, tags, publishes, or GitHub Releases.
|
|
16
|
+
default: false
|
|
17
|
+
|
|
18
|
+
permissions:
|
|
19
|
+
contents: write
|
|
20
|
+
id-token: write
|
|
21
|
+
|
|
22
|
+
concurrency:
|
|
23
|
+
group: release-${{ github.ref }}
|
|
24
|
+
cancel-in-progress: false
|
|
25
|
+
|
|
26
|
+
defaults:
|
|
27
|
+
run:
|
|
28
|
+
working-directory: tooling/direnv
|
|
29
|
+
|
|
30
|
+
jobs:
|
|
31
|
+
publish:
|
|
32
|
+
runs-on: ubuntu-latest
|
|
33
|
+
env:
|
|
34
|
+
NIX_STORE_NAR: ${{ github.workspace }}/nix-store.nar
|
|
35
|
+
GH_TOKEN: ${{ github.token }}
|
|
36
|
+
steps:
|
|
37
|
+
# --- Setup --------------------------------------------------------------
|
|
38
|
+
|
|
39
|
+
# Step 1: GitHub adds "Set up job" automatically
|
|
40
|
+
# Step 2
|
|
41
|
+
- name: 📥 Checkout
|
|
42
|
+
uses: actions/checkout@v6.0.2
|
|
43
|
+
with:
|
|
44
|
+
filter: blob:none
|
|
45
|
+
fetch-depth: 0
|
|
46
|
+
|
|
47
|
+
# Step 3. Composite action internals do not affect top-level job step
|
|
48
|
+
# anchors; update these comments if top-level steps move.
|
|
49
|
+
- name: 🧱 Setup Nix/devenv
|
|
50
|
+
id: setup
|
|
51
|
+
uses: ./.github/actions/setup-devenv
|
|
52
|
+
|
|
53
|
+
# --- Validation ---------------------------------------------------------
|
|
54
|
+
|
|
55
|
+
# Release validation intentionally does not restore persisted Nx task
|
|
56
|
+
# cache. Nx may reuse tasks produced earlier in this same job, but publish
|
|
57
|
+
# never relies on task outputs restored from CI cache.
|
|
58
|
+
|
|
59
|
+
# Step 4
|
|
60
|
+
- name: ✅ Check managed monorepo files
|
|
61
|
+
run: smoo monorepo check
|
|
62
|
+
|
|
63
|
+
# Step 5
|
|
64
|
+
- name: 📦 Resolve release projects
|
|
65
|
+
id: projects
|
|
66
|
+
run: echo "projects=$(smoo monorepo list-public-projects)" >> "$GITHUB_OUTPUT"
|
|
67
|
+
|
|
68
|
+
# Step 6
|
|
69
|
+
- name: 🔨 Build
|
|
70
|
+
run: smoo github-ci nx-run-many --targets build --projects "${{ steps.projects.outputs.projects }}"
|
|
71
|
+
|
|
72
|
+
# Step 7
|
|
73
|
+
- name: 🔍 Lint
|
|
74
|
+
run: smoo github-ci nx-run-many --targets lint --projects "${{ steps.projects.outputs.projects }}"
|
|
75
|
+
|
|
76
|
+
# Step 8
|
|
77
|
+
- name: 🧪 Unit Tests
|
|
78
|
+
run: smoo github-ci nx-run-many --targets test --projects "${{ steps.projects.outputs.projects }}"
|
|
79
|
+
|
|
80
|
+
# Step 9
|
|
81
|
+
- name: 📎 Upload trace DBs
|
|
82
|
+
if: ${{ failure() }}
|
|
83
|
+
uses: actions/upload-artifact@v4
|
|
84
|
+
with:
|
|
85
|
+
name: trace-results-${{ github.run_id }}
|
|
86
|
+
path: packages/*/.trace-results.db
|
|
87
|
+
if-no-files-found: ignore
|
|
88
|
+
retention-days: 14
|
|
89
|
+
include-hidden-files: true
|
|
90
|
+
|
|
91
|
+
# Step 10
|
|
92
|
+
- name: ✅ Validate monorepo config
|
|
93
|
+
run: smoo monorepo validate
|
|
94
|
+
|
|
95
|
+
# --- Release ------------------------------------------------------------
|
|
96
|
+
|
|
97
|
+
# Step 11
|
|
98
|
+
- name: 🤖 Configure release author
|
|
99
|
+
run:
|
|
100
|
+
git config user.name "github-actions[bot]" && git config user.email
|
|
101
|
+
"41898282+github-actions[bot]@users.noreply.github.com"
|
|
102
|
+
|
|
103
|
+
# Step 12
|
|
104
|
+
- name: 🏷️ Version, tag, and push packages
|
|
105
|
+
run: smoo release version --bump "${{ inputs.bump }}" --dry-run "${{ inputs.dry_run }}"
|
|
106
|
+
|
|
107
|
+
# Step 13
|
|
108
|
+
- name: 🔖 Collect release tags
|
|
109
|
+
id: tags
|
|
110
|
+
run: echo "tags=$(git tag --points-at HEAD | tr '\n' ' ')" >> "$GITHUB_OUTPUT"
|
|
111
|
+
|
|
112
|
+
# Step 14
|
|
113
|
+
- name: 📦 Publish packages
|
|
114
|
+
# smoo packs with Bun, then publishes tarballs with npm. npm uses OIDC
|
|
115
|
+
# trusted publishing when configured; NODE_AUTH_TOKEN is only a temporary
|
|
116
|
+
# bootstrap fallback before packages have trusted publishers.
|
|
117
|
+
env:
|
|
118
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
119
|
+
run: smoo release publish --bump "${{ inputs.bump }}" --dry-run "${{ inputs.dry_run }}"
|
|
120
|
+
|
|
121
|
+
# Step 15
|
|
122
|
+
- name: 🚀 Create or update GitHub Releases
|
|
123
|
+
if: ${{ inputs.dry_run != true }}
|
|
124
|
+
run:
|
|
125
|
+
smoo release github-release --tags "${{ steps.tags.outputs.tags }}" --bump "${{ inputs.bump }}" --dry-run "${{
|
|
126
|
+
inputs.dry_run }}"
|
|
127
|
+
|
|
128
|
+
# --- Cleanup ------------------------------------------------------------
|
|
129
|
+
|
|
130
|
+
# Step 16
|
|
131
|
+
- name: 🧹 Cleanup and cache Nix/devenv
|
|
132
|
+
if: ${{ always() }}
|
|
133
|
+
uses: ./.github/actions/save-nix-devenv
|
|
134
|
+
with:
|
|
135
|
+
nix-cache-hit: ${{ steps.setup.outputs.nix-cache-hit }}
|
|
136
|
+
devenv-cache-hit: ${{ steps.setup.outputs.devenv-cache-hit }}
|
package/package.json
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@smoothbricks/cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "SmoothBricks monorepo automation CLI",
|
|
6
|
+
"bin": {
|
|
7
|
+
"smoo": "./bin/smoo"
|
|
8
|
+
},
|
|
9
|
+
"main": "./dist/index.js",
|
|
10
|
+
"module": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"exports": {
|
|
13
|
+
"./package.json": "./package.json",
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"development": "./src/index.ts",
|
|
17
|
+
"import": "./dist/index.js",
|
|
18
|
+
"default": "./dist/index.js"
|
|
19
|
+
},
|
|
20
|
+
"./monorepo/runtime": {
|
|
21
|
+
"types": "./dist/monorepo/runtime.d.ts",
|
|
22
|
+
"bun": "./src/monorepo/runtime.ts",
|
|
23
|
+
"development": "./src/monorepo/runtime.ts",
|
|
24
|
+
"import": "./dist/monorepo/runtime.js",
|
|
25
|
+
"default": "./dist/monorepo/runtime.js"
|
|
26
|
+
},
|
|
27
|
+
"./monorepo/git-config": {
|
|
28
|
+
"types": "./dist/monorepo/git-config.d.ts",
|
|
29
|
+
"bun": "./src/monorepo/git-config.ts",
|
|
30
|
+
"development": "./src/monorepo/git-config.ts",
|
|
31
|
+
"import": "./dist/monorepo/git-config.js",
|
|
32
|
+
"default": "./dist/monorepo/git-config.js"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"README.md",
|
|
37
|
+
"bin",
|
|
38
|
+
"dist",
|
|
39
|
+
"managed",
|
|
40
|
+
"src",
|
|
41
|
+
"!**/*.tsbuildinfo"
|
|
42
|
+
],
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"@arethetypeswrong/cli": "^0.18.2",
|
|
45
|
+
"@smoothbricks/validation": "0.0.1",
|
|
46
|
+
"commander": "^14.0.3",
|
|
47
|
+
"publint": "^0.3.18",
|
|
48
|
+
"sherif": "^1.11.1",
|
|
49
|
+
"tslib": "^2.8.1"
|
|
50
|
+
},
|
|
51
|
+
"nx": {
|
|
52
|
+
"targets": {
|
|
53
|
+
"lint": {}
|
|
54
|
+
},
|
|
55
|
+
"tags": [
|
|
56
|
+
"npm:public"
|
|
57
|
+
]
|
|
58
|
+
},
|
|
59
|
+
"license": "MIT",
|
|
60
|
+
"publishConfig": {
|
|
61
|
+
"access": "public"
|
|
62
|
+
},
|
|
63
|
+
"repository": {
|
|
64
|
+
"type": "git",
|
|
65
|
+
"url": "git+https://github.com/smoothbricks/codebase.git",
|
|
66
|
+
"directory": "packages/cli"
|
|
67
|
+
}
|
|
68
|
+
}
|
package/src/cli.ts
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { Command, CommanderError } from 'commander';
|
|
2
|
+
import { findRepoRoot } from './lib/run.js';
|
|
3
|
+
|
|
4
|
+
export async function runCli(argv = process.argv.slice(2)): Promise<void> {
|
|
5
|
+
const program = buildProgram();
|
|
6
|
+
try {
|
|
7
|
+
await program.parseAsync(argv, { from: 'user' });
|
|
8
|
+
} catch (error) {
|
|
9
|
+
if (error instanceof CommanderError) {
|
|
10
|
+
if (error.code !== 'commander.helpDisplayed') {
|
|
11
|
+
process.exitCode = error.exitCode;
|
|
12
|
+
}
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
16
|
+
console.error(message);
|
|
17
|
+
process.exitCode = 1;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function buildProgram(): Command {
|
|
22
|
+
const program = new Command();
|
|
23
|
+
program.name('smoo').description('SmoothBricks monorepo tooling').exitOverride().showHelpAfterError();
|
|
24
|
+
|
|
25
|
+
const monorepo = program.command('monorepo').description('Manage SmoothBricks-style monorepos');
|
|
26
|
+
monorepo
|
|
27
|
+
.command('init')
|
|
28
|
+
.option('--runtime-only', 'only sync root Bun/Node runtime metadata')
|
|
29
|
+
.option('--sync-runtime', 'sync root Bun/Node runtime metadata outside devenv')
|
|
30
|
+
.action(async (options: { runtimeOnly?: boolean; syncRuntime?: boolean }) => {
|
|
31
|
+
const { initMonorepo } = await import('./monorepo/index.js');
|
|
32
|
+
await initMonorepo(await findRepoRoot(), options);
|
|
33
|
+
});
|
|
34
|
+
monorepo
|
|
35
|
+
.command('validate')
|
|
36
|
+
.option('--fail-fast', 'stop after the first failing validation pack')
|
|
37
|
+
.action(async (options: { failFast?: boolean }) => {
|
|
38
|
+
const { validateMonorepo } = await import('./monorepo/index.js');
|
|
39
|
+
await validateMonorepo(await findRepoRoot(), options);
|
|
40
|
+
});
|
|
41
|
+
monorepo.command('update').action(async () => {
|
|
42
|
+
const { updateManagedFiles } = await import('./monorepo/index.js');
|
|
43
|
+
updateManagedFiles(await findRepoRoot());
|
|
44
|
+
});
|
|
45
|
+
monorepo.command('check').action(async () => {
|
|
46
|
+
const { checkManagedFiles } = await import('./monorepo/index.js');
|
|
47
|
+
checkManagedFiles(await findRepoRoot());
|
|
48
|
+
});
|
|
49
|
+
monorepo.command('diff').action(async () => {
|
|
50
|
+
const { diffManagedFiles } = await import('./monorepo/index.js');
|
|
51
|
+
diffManagedFiles(await findRepoRoot());
|
|
52
|
+
});
|
|
53
|
+
monorepo.command('validate-commit-msg <commitMsgFile>').action(async (commitMsgFile: string) => {
|
|
54
|
+
const { validateCommitMessageFile } = await import('./monorepo/index.js');
|
|
55
|
+
validateCommitMessageFile(commitMsgFile);
|
|
56
|
+
});
|
|
57
|
+
monorepo.command('sync-bun-lockfile-versions').action(async () => {
|
|
58
|
+
const { syncBunLockfileVersions } = await import('./monorepo/index.js');
|
|
59
|
+
syncBunLockfileVersions(await findRepoRoot());
|
|
60
|
+
});
|
|
61
|
+
monorepo.command('list-public-projects').action(async () => {
|
|
62
|
+
const { listPublicProjects } = await import('./monorepo/index.js');
|
|
63
|
+
console.log(listPublicProjects(await findRepoRoot()));
|
|
64
|
+
});
|
|
65
|
+
monorepo.command('validate-public-tags').action(async () => {
|
|
66
|
+
const { validatePublicPackageTags } = await import('./monorepo/index.js');
|
|
67
|
+
validatePublicPackageTags(await findRepoRoot());
|
|
68
|
+
});
|
|
69
|
+
monorepo.command('release-state').action(async () => {
|
|
70
|
+
const { printReleaseState } = await import('./release/index.js');
|
|
71
|
+
await printReleaseState(await findRepoRoot());
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
const release = program.command('release').description('Version, publish, and create GitHub Releases');
|
|
75
|
+
release
|
|
76
|
+
.command('version')
|
|
77
|
+
.option('--bump <bump>', 'auto, patch, minor, major, or prerelease', 'auto')
|
|
78
|
+
.option('--dry-run [dryRun]', 'run without writing versions, tags, or pushes')
|
|
79
|
+
.action(async (options: { bump: string; dryRun?: string | boolean }) => {
|
|
80
|
+
const { releaseVersion } = await import('./release/index.js');
|
|
81
|
+
await releaseVersion(await findRepoRoot(), { bump: options.bump, dryRun: booleanOption(options.dryRun) });
|
|
82
|
+
});
|
|
83
|
+
release
|
|
84
|
+
.command('publish')
|
|
85
|
+
.option('--bump <bump>', 'auto, patch, minor, major, or prerelease', 'auto')
|
|
86
|
+
.option('--tag <tag>', 'explicit npm dist-tag; must match bump-derived tag')
|
|
87
|
+
.option('--npm-tag <npmTag>', 'explicit npm dist-tag; must match bump-derived tag')
|
|
88
|
+
.option('--dry-run [dryRun]', 'run without publishing')
|
|
89
|
+
.action(async (options: { bump: string; tag?: string; npmTag?: string; dryRun?: string | boolean }) => {
|
|
90
|
+
const { releasePublish } = await import('./release/index.js');
|
|
91
|
+
await releasePublish(await findRepoRoot(), { ...options, dryRun: booleanOption(options.dryRun) });
|
|
92
|
+
});
|
|
93
|
+
release
|
|
94
|
+
.command('github-release')
|
|
95
|
+
.option('--tags <tags>', 'space-separated release tags')
|
|
96
|
+
.option('--bump <bump>', 'auto, patch, minor, major, or prerelease', 'auto')
|
|
97
|
+
.option('--tag <tag>', 'explicit npm dist-tag; must match bump-derived tag')
|
|
98
|
+
.option('--npm-tag <npmTag>', 'explicit npm dist-tag; must match bump-derived tag')
|
|
99
|
+
.option('--dry-run [dryRun]', 'skip GitHub Release writes')
|
|
100
|
+
.action(
|
|
101
|
+
async (options: { tags?: string; bump: string; tag?: string; npmTag?: string; dryRun?: string | boolean }) => {
|
|
102
|
+
const { releaseGithubRelease } = await import('./release/index.js');
|
|
103
|
+
await releaseGithubRelease(await findRepoRoot(), { ...options, dryRun: booleanOption(options.dryRun) });
|
|
104
|
+
},
|
|
105
|
+
);
|
|
106
|
+
release
|
|
107
|
+
.command('trust-publisher')
|
|
108
|
+
.description('Configure npm trusted publishing for public packages')
|
|
109
|
+
.option('--dry-run [dryRun]', 'show npm trust changes without saving them')
|
|
110
|
+
.option('--otp <otp>', 'npm one-time password for trust operations')
|
|
111
|
+
.option('--skip-login', 'skip npm browser login before configuring trust')
|
|
112
|
+
.action(async (options: { dryRun?: string | boolean; otp?: string; skipLogin?: boolean }) => {
|
|
113
|
+
const { releaseTrustPublisher } = await import('./release/index.js');
|
|
114
|
+
await releaseTrustPublisher(await findRepoRoot(), {
|
|
115
|
+
dryRun: booleanOption(options.dryRun),
|
|
116
|
+
otp: options.otp,
|
|
117
|
+
skipLogin: options.skipLogin === true,
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
const githubCi = program.command('github-ci').description('GitHub Actions helpers');
|
|
122
|
+
githubCi.command('cleanup-cache').action(async () => {
|
|
123
|
+
const { cleanupGithubCiCache } = await import('./github-ci/index.js');
|
|
124
|
+
await cleanupGithubCiCache(await findRepoRoot());
|
|
125
|
+
});
|
|
126
|
+
githubCi
|
|
127
|
+
.command('nx-smart')
|
|
128
|
+
.requiredOption('--target <target>')
|
|
129
|
+
.option('--name <name>')
|
|
130
|
+
.option('--step <step>')
|
|
131
|
+
.action(async (options: { target: string; name?: string; step?: string }) => {
|
|
132
|
+
const { githubCiNxSmart } = await import('./github-ci/index.js');
|
|
133
|
+
await githubCiNxSmart(await findRepoRoot(), options);
|
|
134
|
+
});
|
|
135
|
+
githubCi
|
|
136
|
+
.command('nx-run-many')
|
|
137
|
+
.requiredOption('--targets <targets>')
|
|
138
|
+
.option('--projects <projects>')
|
|
139
|
+
.action(async (options: { targets: string; projects?: string }) => {
|
|
140
|
+
const { githubCiNxRunMany } = await import('./github-ci/index.js');
|
|
141
|
+
await githubCiNxRunMany(await findRepoRoot(), options);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
return program;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function booleanOption(value: string | boolean | undefined): boolean {
|
|
148
|
+
return value === true || value === 'true';
|
|
149
|
+
}
|