@starci/hfs 4.4.1 → 4.5.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/CHANGELOG.md +5 -0
- package/ci/cli.mjs +64 -0
- package/ci/github.mjs +41 -0
- package/ci/secret.mjs +28 -0
- package/ci/vars.mjs +33 -0
- package/ci/verify.mjs +36 -0
- package/db/backup-receipt.mjs +129 -0
- package/db/dump.mjs +66 -0
- package/db/migrate.mjs +4 -1
- package/db/reset.mjs +125 -0
- package/emit/db-types.mjs +98 -5
- package/lint/run.mjs +28 -6
- package/package.json +2 -1
- package/release/ci-red.mjs +70 -0
- package/release/gate.mjs +50 -10
- package/release/index.mjs +6 -4
- package/runtime/knowledge/hfs/canon-pins.yaml +4 -4
- package/runtime/knowledge/hfs/rules.yaml +95 -4
- package/runtime/modules/kernel/failure-codes.yaml +60 -0
- package/runtime/modules/schemas/application-stacks.schema.yaml +131 -1
- package/runtime/packages/cli/src/catalog.generated.mjs +243 -20
- package/runtime/scripts/hfs/ci-declaration.mjs +102 -0
- package/runtime/scripts/hfs/rules/a15-findings.mjs +9 -0
- package/runtime/scripts/hfs/rules/app-workflow-findings.mjs +10 -0
- package/runtime/scripts/hfs/rules/ci-custody.mjs +104 -0
- package/runtime/scripts/hfs/rules/deploy-workflow.mjs +6 -19
- package/runtime/scripts/hfs/rules/fe-build-args.mjs +142 -0
- package/runtime/scripts/hfs/rules/supply-chain.mjs +40 -3
- package/runtime/scripts/hfs/rules/workflow-contexts.mjs +103 -0
- package/runtime/scripts/lib/secret-patterns.mjs +2 -2
- package/src/main.mjs +17 -6
- package/stack/context.mjs +13 -1
- package/stack/docker-transport.mjs +93 -15
- package/stack/release-store.mjs +12 -7
- package/stack/remote.mjs +14 -6
- package/stack/ssh-session.mjs +178 -0
- package/sync/ci-commands.mjs +103 -1
- package/sync/index.mjs +41 -16
- package/sync/quality-services.mjs +61 -0
- package/sync/readme-badges.mjs +44 -0
- package/sync/stack-images.mjs +29 -3
- package/templates/app/ci-workflows/github/workflows/ci.yml +26 -24
- package/templates/app/ci-workflows/github/workflows/images.yml +24 -2
- package/templates/app/ci-workflows/github/workflows/stack-deploy.yml +8 -2
- package/templates/app/ci-workflows/install-steps.yml +21 -0
- package/templates/app/ci-workflows/sonar-steps.yml +3 -9
- package/templates/app/ci-workflows-lite/github/workflows/ci.yml +28 -35
- package/templates/app/ci-workflows-lite/github/workflows/db-deploy.yml +2 -1
- package/templates/app/ci-workflows-lite/github/workflows/images.yml +24 -2
- package/templates/app/ci-workflows-lite/github/workflows/stack-deploy.yml +8 -2
- package/templates/app/quality-config/codecov.yml +6 -6
- package/templates/app/quality-config/sonar-project.properties +1 -0
- package/templates/app/readme-badges/README.md +1 -0
- package/templates/app/skeleton/.github/dependabot.yml +1 -14
- package/templates/app/skeleton/.starcistacks/application-stacks.yaml +61 -3
- package/templates/app/skeleton/README.md +6 -0
- package/templates/app/skeleton-lite/.github/dependabot.yml +1 -14
- package/templates/app/skeleton-lite/.starcistacks/application-stacks.yaml +57 -3
- package/templates/app/skeleton-lite/README.md +6 -0
- package/templates/app/upgrade-full/.starcistacks/application-stacks.yaml +52 -1
|
@@ -28,7 +28,6 @@ jobs:
|
|
|
28
28
|
STACK_ENVIRONMENT: ${{ inputs.environment }}
|
|
29
29
|
BACKUP_RECEIPT: ${{ inputs.backup_receipt }}
|
|
30
30
|
SOPS_AGE_KEY: ${{ secrets.SOPS_AGE_KEY }}
|
|
31
|
-
XDG_DATA_HOME: ${{ runner.temp }}/starci-data
|
|
32
31
|
steps:
|
|
33
32
|
- name: require release tag
|
|
34
33
|
shell: bash
|
|
@@ -46,6 +45,8 @@ jobs:
|
|
|
46
45
|
with:
|
|
47
46
|
version: v3.13.2
|
|
48
47
|
- name: materialize sealed custody and push migrations
|
|
48
|
+
env:
|
|
49
|
+
XDG_DATA_HOME: ${{ runner.temp }}/starci-data
|
|
49
50
|
shell: bash
|
|
50
51
|
run: |
|
|
51
52
|
set -euo pipefail
|
|
@@ -17,21 +17,43 @@ concurrency:
|
|
|
17
17
|
|
|
18
18
|
jobs:
|
|
19
19
|
image:
|
|
20
|
-
runs-on: ubuntu-latest
|
|
20
|
+
runs-on: ubuntu-latest{{imageJobEnvironment}}
|
|
21
|
+
env:
|
|
22
|
+
STACK_ENVIRONMENT: {{imageEnvironment}}
|
|
21
23
|
strategy:
|
|
22
24
|
fail-fast: false
|
|
23
25
|
matrix:
|
|
24
26
|
include:
|
|
25
27
|
{{imageMatrix}}
|
|
26
|
-
steps:
|
|
28
|
+
steps:{{imageEnvironmentGuard}}
|
|
27
29
|
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
|
|
28
30
|
- name: release tag matches package version
|
|
29
31
|
run: node -e "const version=require('./package.json').version;if(process.env.GITHUB_REF_NAME!=='v'+version)process.exit(1)"
|
|
32
|
+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
|
33
|
+
if: {{imageBuildArgsIf}}
|
|
34
|
+
with:
|
|
35
|
+
node-version: {{nodeMajor}}
|
|
36
|
+
cache: npm
|
|
37
|
+
- run: npm ci --ignore-scripts
|
|
38
|
+
if: {{imageBuildArgsIf}}
|
|
39
|
+
- name: install SOPS
|
|
40
|
+
if: {{imageBuildArgsIf}}
|
|
41
|
+
uses: mdgreenwald/mozilla-sops-action@bb2d96a13ef438ad122e5827a57ebd75d6ff118d # v2.1.0
|
|
42
|
+
with:
|
|
43
|
+
version: v3.13.2
|
|
44
|
+
- name: public build values
|
|
45
|
+
id: args
|
|
46
|
+
if: {{imageBuildArgsIf}}
|
|
47
|
+
env:
|
|
48
|
+
SOPS_AGE_KEY: ${{ secrets.SOPS_AGE_KEY }}
|
|
49
|
+
IMAGE_APP: ${{ matrix.name }}
|
|
50
|
+
run: npx --no-install starci app stack build-args --env "$STACK_ENVIRONMENT" --app "$IMAGE_APP"
|
|
30
51
|
- uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
|
|
31
52
|
- uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
|
|
32
53
|
with:
|
|
33
54
|
context: .
|
|
34
55
|
file: ${{ matrix.file }}
|
|
56
|
+
build-args: ${{ steps.args.outputs.args }}
|
|
35
57
|
push: false
|
|
36
58
|
tags: {{imageProject}}/${{ matrix.name }}:${{ github.ref_name }}
|
|
37
59
|
# OCI keeps the SBOM and provenance attestations without publishing to a registry.
|
|
@@ -50,7 +50,6 @@ jobs:
|
|
|
50
50
|
packages: write
|
|
51
51
|
env:
|
|
52
52
|
STACK_ENVIRONMENT: ${{ inputs.environment }}
|
|
53
|
-
XDG_DATA_HOME: ${{ runner.temp }}/starci-data
|
|
54
53
|
steps:{{stackGuard}}
|
|
55
54
|
- name: require release tag
|
|
56
55
|
shell: bash
|
|
@@ -80,6 +79,7 @@ jobs:
|
|
|
80
79
|
password: ${{ github.token }}{{stackImageSteps}}
|
|
81
80
|
- name: connect to the swarm manager
|
|
82
81
|
env:
|
|
82
|
+
XDG_DATA_HOME: ${{ runner.temp }}/starci-data
|
|
83
83
|
VPS_SSH_KEY: ${{ secrets.VPS_SSH_KEY }}
|
|
84
84
|
VPS_KNOWN_HOSTS: ${{ secrets.VPS_KNOWN_HOSTS }}
|
|
85
85
|
VPS_HOST: ${{ vars.VPS_HOST }}
|
|
@@ -87,11 +87,14 @@ jobs:
|
|
|
87
87
|
run: npx --no-install starci app stack connect --env "$STACK_ENVIRONMENT" --execute
|
|
88
88
|
- name: deploy the release
|
|
89
89
|
env:
|
|
90
|
+
XDG_DATA_HOME: ${{ runner.temp }}/starci-data
|
|
90
91
|
SOPS_AGE_KEY: ${{ secrets.SOPS_AGE_KEY }}{{stackImageEnv}}{{stackPassEnv}}
|
|
91
92
|
run: |
|
|
92
93
|
npx --no-install starci app stack deploy --env "$STACK_ENVIRONMENT" \{{stackImageArgs}}
|
|
93
94
|
--source-sha "$GITHUB_SHA" --execute
|
|
94
95
|
- name: disconnect from the swarm manager
|
|
96
|
+
env:
|
|
97
|
+
XDG_DATA_HOME: ${{ runner.temp }}/starci-data
|
|
95
98
|
if: ${{ always() }}
|
|
96
99
|
run: npx --no-install starci app stack disconnect --env "$STACK_ENVIRONMENT" --execute
|
|
97
100
|
|
|
@@ -105,7 +108,6 @@ jobs:
|
|
|
105
108
|
packages: read
|
|
106
109
|
env:
|
|
107
110
|
STACK_ENVIRONMENT: ${{ inputs.environment }}
|
|
108
|
-
XDG_DATA_HOME: ${{ runner.temp }}/starci-data
|
|
109
111
|
steps:
|
|
110
112
|
- name: require release tag
|
|
111
113
|
shell: bash
|
|
@@ -129,6 +131,7 @@ jobs:
|
|
|
129
131
|
password: ${{ github.token }}
|
|
130
132
|
- name: connect to the swarm manager
|
|
131
133
|
env:
|
|
134
|
+
XDG_DATA_HOME: ${{ runner.temp }}/starci-data
|
|
132
135
|
VPS_SSH_KEY: ${{ secrets.VPS_SSH_KEY }}
|
|
133
136
|
VPS_KNOWN_HOSTS: ${{ secrets.VPS_KNOWN_HOSTS }}
|
|
134
137
|
VPS_HOST: ${{ vars.VPS_HOST }}
|
|
@@ -136,6 +139,7 @@ jobs:
|
|
|
136
139
|
run: npx --no-install starci app stack connect --env "$STACK_ENVIRONMENT" --execute
|
|
137
140
|
- name: redeploy the stored release
|
|
138
141
|
env:
|
|
142
|
+
XDG_DATA_HOME: ${{ runner.temp }}/starci-data
|
|
139
143
|
SOPS_AGE_KEY: ${{ secrets.SOPS_AGE_KEY }}
|
|
140
144
|
RELEASE: ${{ inputs.release }}
|
|
141
145
|
shell: bash
|
|
@@ -144,5 +148,7 @@ jobs:
|
|
|
144
148
|
[ -z "$RELEASE" ] || release=(--release "$RELEASE")
|
|
145
149
|
npx --no-install starci app stack rollback --env "$STACK_ENVIRONMENT" "${release[@]}" --execute
|
|
146
150
|
- name: disconnect from the swarm manager
|
|
151
|
+
env:
|
|
152
|
+
XDG_DATA_HOME: ${{ runner.temp }}/starci-data
|
|
147
153
|
if: ${{ always() }}
|
|
148
154
|
run: npx --no-install starci app stack disconnect --env "$STACK_ENVIRONMENT" --execute
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
{{header}}
|
|
2
2
|
# The be unit run's lcov ({{lcovReport}}), uploaded by the managed CI workflow. Coverage is the logic of be/src/modules/**: the status
|
|
3
3
|
# paths are the measured roots of the one coverage scope (derived from the slot manifest's `coverage` field; its complement is rendered into
|
|
4
|
-
# sonar.coverage.exclusions and its roots into be/jest.config.js), held at
|
|
5
|
-
# service app, plus platform) is held at
|
|
4
|
+
# sonar.coverage.exclusions and its roots into be/jest.config.js), held at {{codecovTarget}} on the project and on the patch, and each component (one per
|
|
5
|
+
# service app, plus platform) is held at {{codecovTarget}} too. fe/ and be/src/features are outside coverage (features are thin by rule; a front end has no tests).
|
|
6
6
|
codecov:
|
|
7
7
|
require_ci_to_pass: true
|
|
8
8
|
coverage:
|
|
9
9
|
status:
|
|
10
10
|
project:
|
|
11
11
|
default:
|
|
12
|
-
target:
|
|
12
|
+
target: {{codecovTarget}}%
|
|
13
13
|
threshold: 0%
|
|
14
14
|
paths:
|
|
15
15
|
{{codecovPaths}}
|
|
16
16
|
patch:
|
|
17
17
|
default:
|
|
18
|
-
target:
|
|
18
|
+
target: {{codecovTarget}}%
|
|
19
19
|
threshold: 0%
|
|
20
20
|
paths:
|
|
21
21
|
{{codecovPaths}}
|
|
@@ -23,10 +23,10 @@ component_management:
|
|
|
23
23
|
default_rules:
|
|
24
24
|
statuses:
|
|
25
25
|
- type: project
|
|
26
|
-
target:
|
|
26
|
+
target: {{codecovTarget}}%
|
|
27
27
|
threshold: 0%
|
|
28
28
|
- type: patch
|
|
29
|
-
target:
|
|
29
|
+
target: {{codecovTarget}}%
|
|
30
30
|
threshold: 0%
|
|
31
31
|
individual_components:
|
|
32
32
|
{{codecovComponents}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{{readmeBadges}}
|
|
@@ -1,17 +1,4 @@
|
|
|
1
1
|
{{header}}
|
|
2
2
|
version: 2
|
|
3
3
|
updates:
|
|
4
|
-
|
|
5
|
-
directory: /
|
|
6
|
-
schedule:
|
|
7
|
-
interval: weekly
|
|
8
|
-
- package-ecosystem: github-actions
|
|
9
|
-
directory: /
|
|
10
|
-
schedule:
|
|
11
|
-
interval: weekly
|
|
12
|
-
- package-ecosystem: docker
|
|
13
|
-
directories:
|
|
14
|
-
- /be/apps/*
|
|
15
|
-
- /fe/apps/*
|
|
16
|
-
schedule:
|
|
17
|
-
interval: weekly
|
|
4
|
+
{{dependabotUpdates}}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# The app declares its topology before any owner provisions a deployment.
|
|
2
2
|
# All-zero application digests are illustrative and must be replaced by verified release digests.
|
|
3
3
|
schema: starci/application-stacks@1
|
|
4
|
+
# To render README badges, declare ci.github: {repository: owner/repo, defaultBranch: main}.
|
|
5
|
+
# A GitHub package.json repository URL also enables the managed block.
|
|
4
6
|
sources:
|
|
5
7
|
- repository: "{{project}}"
|
|
6
8
|
backing:
|
|
@@ -104,8 +106,15 @@ environments:
|
|
|
104
106
|
app: core
|
|
105
107
|
app:
|
|
106
108
|
app: app
|
|
109
|
+
# Public browser configuration; replace the placeholder origin before deployment.
|
|
110
|
+
buildArgs:
|
|
111
|
+
values:
|
|
112
|
+
NEXT_PUBLIC_SITE_URL: "https://{{project}}.example.invalid"
|
|
107
113
|
landing:
|
|
108
114
|
app: landing
|
|
115
|
+
buildArgs:
|
|
116
|
+
values:
|
|
117
|
+
NEXT_PUBLIC_APP_URL: "https://{{project}}.example.invalid"
|
|
109
118
|
volumes:
|
|
110
119
|
- {{project}}-production-ingress-data
|
|
111
120
|
- {{project}}-production-ingress-config-data
|
|
@@ -126,19 +135,68 @@ environments:
|
|
|
126
135
|
k8s:
|
|
127
136
|
status: deferred
|
|
128
137
|
reason: This starter declares Docker Swarm production; no Kubernetes environment is provisioned.
|
|
138
|
+
ci:
|
|
139
|
+
secrets:
|
|
140
|
+
- {name: SONAR_TOKEN, scope: repository, purpose: Sonar analysis token provisioned for this app, optional: true}
|
|
141
|
+
- {name: SOPS_AGE_KEY, scope: environment, environment: production, purpose: Decrypt app members during deployment, optional: true}
|
|
142
|
+
- {name: VPS_SSH_KEY, scope: environment, environment: production, purpose: Deployment SSH key, optional: true}
|
|
143
|
+
- {name: VPS_KNOWN_HOSTS, scope: environment, environment: production, purpose: Pinned deployment SSH host keys, optional: true}
|
|
144
|
+
vars:
|
|
145
|
+
- {name: SONAR_HOST_URL, scope: repository, value: "https://sonar.{{project}}.example.invalid", purpose: Documentation endpoint to replace with this app's public Sonar host, optional: true}
|
|
146
|
+
- {name: VPS_HOST, scope: environment, environment: production, value: 203.0.113.10, purpose: Documentation deployment address to replace before use, optional: true}
|
|
147
|
+
- {name: VPS_USER, scope: environment, environment: production, value: deploy, purpose: Documentation deployment user to replace before use, optional: true}
|
|
129
148
|
services:
|
|
130
149
|
sonar:
|
|
131
150
|
provider: sonarqube
|
|
132
151
|
mode: local
|
|
133
152
|
qualityGate: {{sonarGate}}
|
|
134
|
-
host: {
|
|
153
|
+
host: {local: http://127.0.0.1:9000, public: "https://sonar.{{project}}.example.invalid"}
|
|
135
154
|
stack:
|
|
136
155
|
owner: host
|
|
137
156
|
root: .claude/ext/sonar
|
|
138
157
|
environment: dev
|
|
139
158
|
compose: compose.yaml
|
|
140
159
|
auth: token
|
|
141
|
-
|
|
160
|
+
credentials: []
|
|
161
|
+
projects: [{repository: "{{project}}", key: "{{project}}"}]
|
|
162
|
+
ci: {wiring: optional-follow-up, workflow: .github/workflows/ci.yml, token: SONAR_TOKEN, hostVar: SONAR_HOST_URL}
|
|
142
163
|
ownerAction:
|
|
143
|
-
needed: Provision
|
|
164
|
+
needed: Provision this app's Sonar host and project, then set SONAR_TOKEN with starci app ci secret set and sync SONAR_HOST_URL.
|
|
144
165
|
reason: A fresh app declares its quality service without fabricating credentials or a successful analysis.
|
|
166
|
+
codecov:
|
|
167
|
+
provider: codecov
|
|
168
|
+
mode: hosted
|
|
169
|
+
purpose: Report application coverage through GitHub OIDC.
|
|
170
|
+
auth: oidc
|
|
171
|
+
target: 100
|
|
172
|
+
components: auto
|
|
173
|
+
required: true
|
|
174
|
+
ci: {wiring: optional-follow-up, workflow: .github/workflows/ci.yml}
|
|
175
|
+
ownerAction: none
|
|
176
|
+
dependabot:
|
|
177
|
+
provider: github
|
|
178
|
+
mode: hosted
|
|
179
|
+
purpose: Keep application dependencies and workflow actions current.
|
|
180
|
+
ecosystems: [npm, docker, github-actions]
|
|
181
|
+
schedule: {interval: weekly}
|
|
182
|
+
groups: {minorPatch: grouped, major: per-package}
|
|
183
|
+
ignore: ['@starci/*']
|
|
184
|
+
security: immediate
|
|
185
|
+
ownerAction: none
|
|
186
|
+
audit:
|
|
187
|
+
provider: npm
|
|
188
|
+
mode: local
|
|
189
|
+
purpose: Refuse high severity production dependency vulnerabilities.
|
|
190
|
+
level: high
|
|
191
|
+
omitDev: true
|
|
192
|
+
in: [release-gate, ci]
|
|
193
|
+
ownerAction: none
|
|
194
|
+
container-registry:
|
|
195
|
+
provider: ghcr
|
|
196
|
+
mode: hosted
|
|
197
|
+
purpose: Publish this app's deployment images with the workflow GitHub token.
|
|
198
|
+
host: {public: https://ghcr.io}
|
|
199
|
+
auth: github-token
|
|
200
|
+
projects: [{repository: "{{project}}", key: "{{project}}"}]
|
|
201
|
+
ci: {wiring: optional-follow-up}
|
|
202
|
+
ownerAction: none
|
|
@@ -16,6 +16,10 @@ TypeScript everywhere; NestJS in `be/`, Next.js with next-intl in `fe/`; npm wit
|
|
|
16
16
|
- `fe/`: the front end, one Next app per `fe/apps/<app>` and the shared workspace packages under `fe/packages/` (the ui drawings and the next-intl stack both apps call).
|
|
17
17
|
- `scripts/`: the app's operational scripts; `hfs.json` declares both sides.
|
|
18
18
|
|
|
19
|
+
## Status badges
|
|
20
|
+
|
|
21
|
+
Declare `ci.github.repository` and `ci.github.defaultBranch` in `.starcistacks/application-stacks.yaml` (or set the GitHub `repository` URL in `package.json`), then run `npx starci app sync --write`. Sync inserts a managed badge block after the title; `npx starci app sync --check` verifies it.
|
|
22
|
+
|
|
19
23
|
## Development
|
|
20
24
|
|
|
21
25
|
```sh
|
|
@@ -33,6 +37,8 @@ requests) and `PRIMARY_DB_URL` at boot; every door is closed until it is marked
|
|
|
33
37
|
`npm run cli -- seed run` runs the dev seeds of `.starcistacks/dev/seeds` (run both from the app root). The product app reads
|
|
34
38
|
`NEXT_PUBLIC_SITE_URL` and `NEXT_PUBLIC_GRAPHQL_URL` (the back end it calls through `fe/apps/app/src/modules/api`, read once the first GraphQL operation exists), the landing `NEXT_PUBLIC_APP_URL` (the product app it hands the reader over to). A missing key stops the process with an error that names it.
|
|
35
39
|
|
|
40
|
+
Production browser build values live in `.starcistacks/application-stacks.yaml` under `environments.production.deploy.images.*.buildArgs.values`. Replace the placeholder origins for the product's `NEXT_PUBLIC_SITE_URL` and the landing's `NEXT_PUBLIC_APP_URL` with your product app's public origin before building deployment images.
|
|
41
|
+
|
|
36
42
|
## Work
|
|
37
43
|
|
|
38
44
|
The product's Work records live in `.starciwork`.
|
|
@@ -1,17 +1,4 @@
|
|
|
1
1
|
{{header}}
|
|
2
2
|
version: 2
|
|
3
3
|
updates:
|
|
4
|
-
|
|
5
|
-
directory: /
|
|
6
|
-
schedule:
|
|
7
|
-
interval: weekly
|
|
8
|
-
- package-ecosystem: github-actions
|
|
9
|
-
directory: /
|
|
10
|
-
schedule:
|
|
11
|
-
interval: weekly
|
|
12
|
-
- package-ecosystem: docker
|
|
13
|
-
directories:
|
|
14
|
-
- /be/apps/*
|
|
15
|
-
- /fe/apps/*
|
|
16
|
-
schedule:
|
|
17
|
-
interval: weekly
|
|
4
|
+
{{dependabotUpdates}}
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
# The source models declare intended compute; they prove no completed deployment.
|
|
3
3
|
# All-zero application digests are illustrative and must be replaced by verified release digests.
|
|
4
4
|
schema: starci/application-stacks@1
|
|
5
|
+
# To render README badges, declare ci.github: {repository: owner/repo, defaultBranch: main}.
|
|
6
|
+
# A GitHub package.json repository URL also enables the managed block.
|
|
5
7
|
sources:
|
|
6
8
|
- repository: {{project}}
|
|
7
9
|
backing:
|
|
@@ -145,9 +147,12 @@ environments:
|
|
|
145
147
|
app: api
|
|
146
148
|
web:
|
|
147
149
|
app: web
|
|
150
|
+
# Public browser configuration; replace these placeholders before deployment.
|
|
148
151
|
buildArgs:
|
|
149
152
|
values:
|
|
150
153
|
NEXT_PUBLIC_SITE_URL: "https://{{project}}.example.invalid"
|
|
154
|
+
NEXT_PUBLIC_SUPABASE_URL: "https://supabase.{{project}}.example.invalid"
|
|
155
|
+
NEXT_PUBLIC_SUPABASE_ANON_KEY: "REPLACE_WITH_PUBLIC_SUPABASE_ANON_KEY"
|
|
151
156
|
volumes:
|
|
152
157
|
- {{project}}-production-ingress-data
|
|
153
158
|
- {{project}}-production-ingress-config-data
|
|
@@ -175,19 +180,68 @@ environments:
|
|
|
175
180
|
k8s:
|
|
176
181
|
status: deferred
|
|
177
182
|
reason: Lite production uses Docker Swarm with managed Supabase backing; Kubernetes belongs to a future full-edition deployment.
|
|
183
|
+
ci:
|
|
184
|
+
secrets:
|
|
185
|
+
- {name: SONAR_TOKEN, scope: repository, purpose: Sonar analysis token provisioned for this app, optional: true}
|
|
186
|
+
- {name: SOPS_AGE_KEY, scope: environment, environment: production, purpose: Decrypt app members during deployment, optional: true}
|
|
187
|
+
- {name: VPS_SSH_KEY, scope: environment, environment: production, purpose: Deployment SSH key, optional: true}
|
|
188
|
+
- {name: VPS_KNOWN_HOSTS, scope: environment, environment: production, purpose: Pinned deployment SSH host keys, optional: true}
|
|
189
|
+
vars:
|
|
190
|
+
- {name: SONAR_HOST_URL, scope: repository, value: "https://sonar.{{project}}.example.invalid", purpose: Documentation endpoint to replace with this app's public Sonar host, optional: true}
|
|
191
|
+
- {name: VPS_HOST, scope: environment, environment: production, value: 203.0.113.10, purpose: Documentation deployment address to replace before use, optional: true}
|
|
192
|
+
- {name: VPS_USER, scope: environment, environment: production, value: deploy, purpose: Documentation deployment user to replace before use, optional: true}
|
|
178
193
|
services:
|
|
179
194
|
sonar:
|
|
180
195
|
provider: sonarqube
|
|
181
196
|
mode: local
|
|
182
197
|
qualityGate: {{sonarGate}}
|
|
183
|
-
host: {local: http://127.0.0.1:9000}
|
|
198
|
+
host: {local: http://127.0.0.1:9000, public: "https://sonar.{{project}}.example.invalid"}
|
|
184
199
|
stack:
|
|
185
200
|
owner: host
|
|
186
201
|
root: .claude/ext/sonar
|
|
187
202
|
environment: dev
|
|
188
203
|
compose: compose.yaml
|
|
189
204
|
auth: token
|
|
190
|
-
|
|
205
|
+
credentials: []
|
|
206
|
+
projects: [{repository: "{{project}}", key: "{{project}}"}]
|
|
207
|
+
ci: {wiring: optional-follow-up, workflow: .github/workflows/ci.yml, token: SONAR_TOKEN, hostVar: SONAR_HOST_URL}
|
|
191
208
|
ownerAction:
|
|
192
|
-
needed: Provision
|
|
209
|
+
needed: Provision this app's Sonar host and project, then set SONAR_TOKEN with starci app ci secret set and sync SONAR_HOST_URL.
|
|
193
210
|
reason: A fresh app declares its quality service without fabricating credentials or a successful analysis.
|
|
211
|
+
codecov:
|
|
212
|
+
provider: codecov
|
|
213
|
+
mode: hosted
|
|
214
|
+
purpose: Report application coverage through GitHub OIDC.
|
|
215
|
+
auth: oidc
|
|
216
|
+
target: 100
|
|
217
|
+
components: auto
|
|
218
|
+
required: true
|
|
219
|
+
ci: {wiring: optional-follow-up, workflow: .github/workflows/ci.yml}
|
|
220
|
+
ownerAction: none
|
|
221
|
+
dependabot:
|
|
222
|
+
provider: github
|
|
223
|
+
mode: hosted
|
|
224
|
+
purpose: Keep application dependencies and workflow actions current.
|
|
225
|
+
ecosystems: [npm, docker, github-actions]
|
|
226
|
+
schedule: {interval: weekly}
|
|
227
|
+
groups: {minorPatch: grouped, major: per-package}
|
|
228
|
+
ignore: ['@starci/*']
|
|
229
|
+
security: immediate
|
|
230
|
+
ownerAction: none
|
|
231
|
+
audit:
|
|
232
|
+
provider: npm
|
|
233
|
+
mode: local
|
|
234
|
+
purpose: Refuse high severity production dependency vulnerabilities.
|
|
235
|
+
level: high
|
|
236
|
+
omitDev: true
|
|
237
|
+
in: [release-gate, ci]
|
|
238
|
+
ownerAction: none
|
|
239
|
+
container-registry:
|
|
240
|
+
provider: ghcr
|
|
241
|
+
mode: hosted
|
|
242
|
+
purpose: Publish this app's deployment images with the workflow GitHub token.
|
|
243
|
+
host: {public: https://ghcr.io}
|
|
244
|
+
auth: github-token
|
|
245
|
+
projects: [{repository: "{{project}}", key: "{{project}}"}]
|
|
246
|
+
ci: {wiring: optional-follow-up}
|
|
247
|
+
ownerAction: none
|
|
@@ -18,6 +18,10 @@ TypeScript everywhere, NestJS in `be/`, Next.js with next-intl in `fe/`, Supabas
|
|
|
18
18
|
- `.starcistacks/`: value-free environment metadata and encrypted-secret custody.
|
|
19
19
|
- `.starciwork/`: `.gitignore`, `.starciwork/workspace.yaml` project metadata and repo roles, and optional brand drawing records, references, and assets.
|
|
20
20
|
|
|
21
|
+
## Status badges
|
|
22
|
+
|
|
23
|
+
Declare `ci.github.repository` and `ci.github.defaultBranch` in `.starcistacks/application-stacks.yaml` (or set the GitHub `repository` URL in `package.json`), then run `npx starci app sync --write`. Sync inserts a managed badge block after the title; `npx starci app sync --check` verifies it.
|
|
24
|
+
|
|
21
25
|
## Development
|
|
22
26
|
|
|
23
27
|
```sh
|
|
@@ -32,6 +36,8 @@ npm run build:fe
|
|
|
32
36
|
|
|
33
37
|
The API reads `PORT`, `HTTP_SECURITY_ALLOWED_ORIGINS`, `PRIMARY_DB_URL`, `PRIMARY_DB_SCHEMA`, `SUPABASE_URL`, and `SUPABASE_SERVICE_ROLE_KEY`. The web app reads `NEXT_PUBLIC_SITE_URL`, `NEXT_PUBLIC_SUPABASE_URL`, `NEXT_PUBLIC_SUPABASE_ANON_KEY`, and, once the first GraphQL operation exists, `NEXT_PUBLIC_GRAPHQL_URL`. Missing configuration stops the relevant process with a named error; no template supplies credential defaults.
|
|
34
38
|
|
|
39
|
+
Production browser build values live in `.starcistacks/application-stacks.yaml` under `environments.production.deploy.images.web.buildArgs.values`. Before building deployment images, replace the placeholders with your site's public origin, your Supabase project's public URL, and its public anonymous key. These values reach every browser; keep the service role key in sealed runtime custody.
|
|
40
|
+
|
|
35
41
|
`npm test` runs the back end's unit specs with per-file coverage. Optional integration specs run with `npm run test:integration` against the local Supabase stack (`npm run db:start`); a lite app has no e2e world.
|
|
36
42
|
|
|
37
43
|
The public runtime template tracks only sealed member names. Scaffolding creates this app's own age recipient and encrypts generated placeholder values into the declared `.starcistacks/<environment>/secrets/*.enc` members. Keep the matching host age identity in untracked local custody, then use `starci app secret set` to replace each placeholder with an actual value before deployment. Product apps retain sealed member custody. Runtime specs use disposable copies with ephemeral identities and remove them afterwards.
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
schema: starci/application-stacks@1
|
|
2
|
+
# To render README badges, declare ci.github: {repository: owner/repo, defaultBranch: main}.
|
|
3
|
+
# A GitHub package.json repository URL also enables the managed block.
|
|
2
4
|
sources:
|
|
3
5
|
- repository: "{{project}}"
|
|
4
6
|
components:
|
|
@@ -28,11 +30,60 @@ environments:
|
|
|
28
30
|
k8s:
|
|
29
31
|
status: deferred
|
|
30
32
|
reason: The upgrade establishes the full local stack first; deployment topology is selected separately.
|
|
33
|
+
ci:
|
|
34
|
+
secrets:
|
|
35
|
+
- {name: SONAR_TOKEN, scope: repository, purpose: Sonar analysis token provisioned for this app, optional: true}
|
|
36
|
+
- {name: SOPS_AGE_KEY, scope: repository, purpose: Decrypt app members during deployment, optional: true}
|
|
37
|
+
- {name: VPS_SSH_KEY, scope: repository, purpose: Deployment SSH key, optional: true}
|
|
38
|
+
- {name: VPS_KNOWN_HOSTS, scope: repository, purpose: Pinned deployment SSH host keys, optional: true}
|
|
39
|
+
vars:
|
|
40
|
+
- {name: SONAR_HOST_URL, scope: repository, value: "https://sonar.{{project}}.example.invalid", purpose: Documentation endpoint to replace with this app's public Sonar host, optional: true}
|
|
41
|
+
- {name: VPS_HOST, scope: repository, value: 203.0.113.10, purpose: Documentation deployment address to replace before use, optional: true}
|
|
42
|
+
- {name: VPS_USER, scope: repository, value: deploy, purpose: Documentation deployment user to replace before use, optional: true}
|
|
31
43
|
services:
|
|
32
44
|
sonar:
|
|
33
45
|
provider: sonarqube
|
|
34
46
|
mode: disabled
|
|
35
47
|
reason: Enable the repository's Sonar service when a host and project token are provisioned.
|
|
36
48
|
qualityGate: starci-quality
|
|
37
|
-
|
|
49
|
+
credentials: []
|
|
50
|
+
projects: [{repository: "{{project}}", key: "{{project}}"}]
|
|
51
|
+
ci: {wiring: optional-follow-up, workflow: .github/workflows/ci.yml, token: SONAR_TOKEN, hostVar: SONAR_HOST_URL}
|
|
52
|
+
ownerAction: none
|
|
53
|
+
codecov:
|
|
54
|
+
provider: codecov
|
|
55
|
+
mode: hosted
|
|
56
|
+
purpose: Report application coverage through GitHub OIDC.
|
|
57
|
+
auth: oidc
|
|
58
|
+
target: 100
|
|
59
|
+
components: auto
|
|
60
|
+
required: true
|
|
61
|
+
ci: {wiring: optional-follow-up, workflow: .github/workflows/ci.yml}
|
|
62
|
+
ownerAction: none
|
|
63
|
+
dependabot:
|
|
64
|
+
provider: github
|
|
65
|
+
mode: hosted
|
|
66
|
+
purpose: Keep application dependencies and workflow actions current.
|
|
67
|
+
ecosystems: [npm, docker, github-actions]
|
|
68
|
+
schedule: {interval: weekly}
|
|
69
|
+
groups: {minorPatch: grouped, major: per-package}
|
|
70
|
+
ignore: ['@starci/*']
|
|
71
|
+
security: immediate
|
|
72
|
+
ownerAction: none
|
|
73
|
+
audit:
|
|
74
|
+
provider: npm
|
|
75
|
+
mode: local
|
|
76
|
+
purpose: Refuse high severity production dependency vulnerabilities.
|
|
77
|
+
level: high
|
|
78
|
+
omitDev: true
|
|
79
|
+
in: [release-gate, ci]
|
|
80
|
+
ownerAction: none
|
|
81
|
+
container-registry:
|
|
82
|
+
provider: ghcr
|
|
83
|
+
mode: hosted
|
|
84
|
+
purpose: Publish this app's deployment images with the workflow GitHub token.
|
|
85
|
+
host: {public: https://ghcr.io}
|
|
86
|
+
auth: github-token
|
|
87
|
+
projects: [{repository: "{{project}}", key: "{{project}}"}]
|
|
88
|
+
ci: {wiring: optional-follow-up}
|
|
38
89
|
ownerAction: none
|