@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.
Files changed (60) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/ci/cli.mjs +64 -0
  3. package/ci/github.mjs +41 -0
  4. package/ci/secret.mjs +28 -0
  5. package/ci/vars.mjs +33 -0
  6. package/ci/verify.mjs +36 -0
  7. package/db/backup-receipt.mjs +129 -0
  8. package/db/dump.mjs +66 -0
  9. package/db/migrate.mjs +4 -1
  10. package/db/reset.mjs +125 -0
  11. package/emit/db-types.mjs +98 -5
  12. package/lint/run.mjs +28 -6
  13. package/package.json +2 -1
  14. package/release/ci-red.mjs +70 -0
  15. package/release/gate.mjs +50 -10
  16. package/release/index.mjs +6 -4
  17. package/runtime/knowledge/hfs/canon-pins.yaml +4 -4
  18. package/runtime/knowledge/hfs/rules.yaml +95 -4
  19. package/runtime/modules/kernel/failure-codes.yaml +60 -0
  20. package/runtime/modules/schemas/application-stacks.schema.yaml +131 -1
  21. package/runtime/packages/cli/src/catalog.generated.mjs +243 -20
  22. package/runtime/scripts/hfs/ci-declaration.mjs +102 -0
  23. package/runtime/scripts/hfs/rules/a15-findings.mjs +9 -0
  24. package/runtime/scripts/hfs/rules/app-workflow-findings.mjs +10 -0
  25. package/runtime/scripts/hfs/rules/ci-custody.mjs +104 -0
  26. package/runtime/scripts/hfs/rules/deploy-workflow.mjs +6 -19
  27. package/runtime/scripts/hfs/rules/fe-build-args.mjs +142 -0
  28. package/runtime/scripts/hfs/rules/supply-chain.mjs +40 -3
  29. package/runtime/scripts/hfs/rules/workflow-contexts.mjs +103 -0
  30. package/runtime/scripts/lib/secret-patterns.mjs +2 -2
  31. package/src/main.mjs +17 -6
  32. package/stack/context.mjs +13 -1
  33. package/stack/docker-transport.mjs +93 -15
  34. package/stack/release-store.mjs +12 -7
  35. package/stack/remote.mjs +14 -6
  36. package/stack/ssh-session.mjs +178 -0
  37. package/sync/ci-commands.mjs +103 -1
  38. package/sync/index.mjs +41 -16
  39. package/sync/quality-services.mjs +61 -0
  40. package/sync/readme-badges.mjs +44 -0
  41. package/sync/stack-images.mjs +29 -3
  42. package/templates/app/ci-workflows/github/workflows/ci.yml +26 -24
  43. package/templates/app/ci-workflows/github/workflows/images.yml +24 -2
  44. package/templates/app/ci-workflows/github/workflows/stack-deploy.yml +8 -2
  45. package/templates/app/ci-workflows/install-steps.yml +21 -0
  46. package/templates/app/ci-workflows/sonar-steps.yml +3 -9
  47. package/templates/app/ci-workflows-lite/github/workflows/ci.yml +28 -35
  48. package/templates/app/ci-workflows-lite/github/workflows/db-deploy.yml +2 -1
  49. package/templates/app/ci-workflows-lite/github/workflows/images.yml +24 -2
  50. package/templates/app/ci-workflows-lite/github/workflows/stack-deploy.yml +8 -2
  51. package/templates/app/quality-config/codecov.yml +6 -6
  52. package/templates/app/quality-config/sonar-project.properties +1 -0
  53. package/templates/app/readme-badges/README.md +1 -0
  54. package/templates/app/skeleton/.github/dependabot.yml +1 -14
  55. package/templates/app/skeleton/.starcistacks/application-stacks.yaml +61 -3
  56. package/templates/app/skeleton/README.md +6 -0
  57. package/templates/app/skeleton-lite/.github/dependabot.yml +1 -14
  58. package/templates/app/skeleton-lite/.starcistacks/application-stacks.yaml +57 -3
  59. package/templates/app/skeleton-lite/README.md +6 -0
  60. package/templates/app/upgrade-full/.starcistacks/application-stacks.yaml +52 -1
@@ -3503,12 +3503,13 @@ rules:
3503
3503
  - {path: packages/hfs/templates/app/skeleton-lite/supabase/config.toml, edition: lite}
3504
3504
  templateNa: "Database types are generated from each app migration set, not static templates; full-edition Supabase configuration is app-owned."
3505
3505
  witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
3506
- law: "The database configuration and its types are checked facts: `supabase/config.toml` carries no literal value under a credential key (the value is `env(NAME)`), `auth.jwt_expiry` is at most 3600, and signup, site url and redirect urls equal the Supabase block of hfs.json where it declares them; `supabase/types/database.types.ts` is committed and equals the text `contract:emit` regenerates from the migrations."
3506
+ law: "The database configuration and its types are checked facts: `supabase/config.toml` carries no literal value under a credential key (the value is `env(NAME)`), `auth.jwt_expiry` is at most 3600, and signup, site url and redirect urls equal the Supabase block of hfs.json where it declares them; `supabase/types/database.types.ts` is committed and equals the text `contract:emit` regenerates from the migrations. Type emission refuses HFS_EMIT_DB_TYPES_STALE unless the complete applied migration version set equals the SQL filename stamps; lint and check report drift without writing types."
3507
3507
  kinds: [check]
3508
3508
  gates: [land, ci]
3509
- failureCodes: ["DB_CONFIG_POLICY", "DB_TYPES_DRIFT"]
3509
+ failureCodes: ["DB_CONFIG_POLICY", "DB_TYPES_DRIFT", "HFS_EMIT_DB_TYPES_STALE"]
3510
3510
  enforcers:
3511
3511
  - {kind: hfs, id: db-config-types, at: scripts/hfs/rules/database.mjs}
3512
+ - {kind: hfs, id: db-types-emit, at: packages/hfs/emit/db-types.mjs}
3512
3513
  - id: R217
3513
3514
  code: "FE_SUPABASE_CLIENT_OWNER"
3514
3515
  editions: [lite, full]
@@ -4025,12 +4026,13 @@ rules:
4025
4026
  - {path: packages/hfs/templates/app/ci-workflows-lite/github/workflows/db-deploy.yml, edition: lite}
4026
4027
  - {path: packages/hfs/templates/app/ci-workflows/github/workflows/ci.yml, edition: full}
4027
4028
  witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
4028
- law: "In lite and full apps, deployment jobs declare a protected environment, explicit permissions and concurrency, materialize sealed secrets through SOPS_AGE_KEY or starci app secret materialize, and reference only the age key and transport SSH key/known_hosts secrets. They never embed a dotenv blob or write a dotenv file. Every remote workflow action uses a 40-hex commit SHA; installed tools are checksum or digest verified, or supplied by a pinned action. App workflows start only on release tags [v*] or workflow_dispatch, never on a branch push."
4029
+ law: "In lite and full apps, deployment jobs declare a protected environment, explicit permissions and concurrency, materialize sealed secrets through SOPS_AGE_KEY or starci app secret materialize, and reference only the age key and transport SSH key/known_hosts secrets. They never embed a dotenv blob or write a dotenv file. Every remote workflow action uses a 40-hex commit SHA (local actions are allowed and container actions require a full sha256 digest); supply-chain reports each unpinned uses reference at its source line, including disabled jobs and steps; installed tools are checksum or digest verified, or supplied by a pinned action. App workflows start only on release tags [v*] or workflow_dispatch, never on a branch push."
4029
4030
  kinds: [check]
4030
4031
  gates: [settle, land, ci]
4031
4032
  failureCodes: ["HFS_DEPLOY_WORKFLOW", "HFS_WORKFLOW_PIN", "HFS_CI_TOOL_INSTALL", "HFS_APP_WORKFLOW_TRIGGER"]
4032
4033
  enforcers:
4033
4034
  - {kind: hfs, id: deploy-workflow, at: scripts/hfs/rules/deploy-workflow.mjs}
4035
+ - {kind: hfs, id: supply-chain, at: scripts/hfs/rules/supply-chain.mjs}
4034
4036
  exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
4035
4037
  - id: R252
4036
4038
  code: "HFS_SCRIPT_PLAINTEXT_LOAD"
@@ -4359,7 +4361,7 @@ rules:
4359
4361
  exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
4360
4362
  - id: R269
4361
4363
  code: "HFS_DEPENDABOT_MISSING"
4362
- law: "In lite and full apps, .github/dependabot.yml declares scheduled npm, github-actions and docker updates. The CI workflow runs npm audit --omit=dev as an enabled gate whose failure stops the job. The images workflow generates an SBOM and provenance for release images; a disabled step, comment or label is not evidence."
4364
+ law: "In lite and full apps, .github/dependabot.yml declares scheduled npm, github-actions and docker updates. Every npm entry declares a minor-and-patch version group and a security-updates group; every group explicitly restricts update-types to minor and patch, leaving majors per package, and npm entries ignore @starci/* without version or update-type restrictions. The CI workflow runs npm audit --omit=dev as an enabled gate whose failure stops the job. The images workflow generates an SBOM and provenance for release images; a disabled step, comment or label is not evidence."
4363
4365
  kinds: [check]
4364
4366
  gates: ["settle","land","ci"]
4365
4367
  failureCodes: ["HFS_DEPENDABOT_MISSING", "HFS_AUDIT_STEP_MISSING", "HFS_SBOM_MISSING"]
@@ -4876,3 +4878,92 @@ rules:
4876
4878
  - {path: packages/eslint/be/module-shape.spec.mjs, editions: [lite, full], codes: [BE_MODULE_DEFINITION_MISSING]}
4877
4879
  witness:
4878
4880
  - {path: packages/eslint/be/module-shape.spec.mjs, editions: [lite, full], codes: [BE_MODULE_DEFINITION_MISSING]}
4881
+ - id: R296
4882
+ code: "CI_SECRET_SEALED"
4883
+ law: "A name declared in ci.secrets or ci.dependabot.secrets never names a key stored inside an app sealed .starcistacks/<env>/secrets/<member>.enc member. App runtime and CI custody are separate; checks inspect key names without decrypting or printing values."
4884
+ kinds: [check]
4885
+ gates: [settle, land, ci]
4886
+ failureCodes: ["CI_SECRET_SEALED"]
4887
+ enforcers:
4888
+ - {kind: hfs, id: ci-custody, at: scripts/hfs/rules/ci-custody.mjs}
4889
+ editions: [lite, full]
4890
+ docs:
4891
+ - {path: docs/application-stacks.md#r296, editions: [lite, full]}
4892
+ exemplifiedBy:
4893
+ - {path: examples/lite-app/.starcistacks/application-stacks.yaml, edition: lite}
4894
+ - {path: examples/ecommerce-app/.starcistacks/application-stacks.yaml, edition: full}
4895
+ - {path: examples/shape-slot/.starcistacks/application-stacks.yaml, edition: full}
4896
+ - {path: packages/hfs/templates/app/skeleton-lite/.starcistacks/application-stacks.yaml, edition: lite}
4897
+ - {path: packages/hfs/templates/app/skeleton/.starcistacks/application-stacks.yaml, edition: full}
4898
+ specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
4899
+ witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
4900
+ - id: R297
4901
+ code: "APP_SECRET_IN_CI"
4902
+ law: "A sealed member key granted to an app container by a deploy grant never appears in ci.secrets or ci.vars. The grant environment, member and selected key determine app custody; online GitHub custody is verified by starci app ci verify."
4903
+ kinds: [check]
4904
+ gates: [settle, land, ci]
4905
+ failureCodes: ["APP_SECRET_IN_CI"]
4906
+ enforcers:
4907
+ - {kind: hfs, id: ci-custody, at: scripts/hfs/rules/ci-custody.mjs}
4908
+ editions: [lite, full]
4909
+ docs:
4910
+ - {path: docs/application-stacks.md#r297, editions: [lite, full]}
4911
+ exemplifiedBy:
4912
+ - {path: examples/lite-app/.starcistacks/application-stacks.yaml, edition: lite}
4913
+ - {path: examples/ecommerce-app/.starcistacks/application-stacks.yaml, edition: full}
4914
+ - {path: examples/shape-slot/.starcistacks/application-stacks.yaml, edition: full}
4915
+ - {path: packages/hfs/templates/app/skeleton-lite/.starcistacks/application-stacks.yaml, edition: lite}
4916
+ - {path: packages/hfs/templates/app/skeleton/.starcistacks/application-stacks.yaml, edition: full}
4917
+ specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
4918
+ witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
4919
+ - id: R298
4920
+ code: "CI_DECLARATION_DRIFT"
4921
+ law: "Workflow secrets and vars references are declared in their matching top-level ci class, except automatic GITHUB_TOKEN. Non-optional Actions declarations are consumed by a workflow; Dependabot secrets need no Actions read. Service token and variable bindings name declarations in the matching class. Missing declarations produce migration findings; a tree with neither ci declarations nor references stays quiet."
4922
+ kinds: [check]
4923
+ gates: [settle, land, ci]
4924
+ failureCodes: ["CI_DECLARATION_DRIFT"]
4925
+ enforcers:
4926
+ - {kind: hfs, id: ci-custody, at: scripts/hfs/rules/ci-custody.mjs}
4927
+ editions: [lite, full]
4928
+ docs:
4929
+ - {path: docs/application-stacks.md#r298, editions: [lite, full]}
4930
+ exemplifiedBy:
4931
+ - {path: examples/lite-app/.starcistacks/application-stacks.yaml, edition: lite}
4932
+ - {path: examples/ecommerce-app/.starcistacks/application-stacks.yaml, edition: full}
4933
+ - {path: examples/shape-slot/.starcistacks/application-stacks.yaml, edition: full}
4934
+ - {path: packages/hfs/templates/app/skeleton-lite/.starcistacks/application-stacks.yaml, edition: lite}
4935
+ - {path: packages/hfs/templates/app/skeleton/.starcistacks/application-stacks.yaml, edition: full}
4936
+ specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
4937
+ witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
4938
+ - id: R299
4939
+ code: "HFS_WORKFLOW_CONTEXT"
4940
+ law: "GitHub Actions expressions use only contexts available at their workflow key. Job env cannot read runner, job, steps or env; runner-local data paths belong to step env or shell RUNNER_TEMP. Every tracked workflow is checked in both app editions."
4941
+ kinds: [check]
4942
+ gates: [settle, land, ci]
4943
+ failureCodes: ["HFS_WORKFLOW_CONTEXT"]
4944
+ enforcers:
4945
+ - {kind: hfs, id: workflow-contexts, at: scripts/hfs/rules/workflow-contexts.mjs}
4946
+ editions: [lite, full]
4947
+ docs:
4948
+ - {path: docs/application-stacks.md#r299, editions: [lite, full]}
4949
+ exemplifiedBy:
4950
+ - {path: packages/hfs/templates/app/skeleton-lite/.starcistacks, edition: lite}
4951
+ - {path: packages/hfs/templates/app/skeleton/.starcistacks, edition: full}
4952
+ specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
4953
+ witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): no runtime spec retained", date: "2026-10-17"}
4954
+ - id: R300
4955
+ code: "FE_PUBLIC_BUILD_ARG_MISSING"
4956
+ law: "Every front-end app with a Dockerfile supplies each required NEXT_PUBLIC_* source/config/schema name through a Dockerfile ARG default or through that image's buildArgs.values/buildArgs.sealed.keys in every environment deploying the image. Source reads with literal string ?? or || fallbacks are optional. The finding names missing keys and environments at the Dockerfile; sealed values are never opened. CI release images use the same starci app stack build-args verb and environment as deployment."
4957
+ kinds: [check]
4958
+ gates: [settle, land, ci]
4959
+ failureCodes: ["FE_PUBLIC_BUILD_ARG_MISSING"]
4960
+ enforcers:
4961
+ - {kind: hfs, id: fe-build-args, at: scripts/hfs/rules/fe-build-args.mjs}
4962
+ editions: [lite, full]
4963
+ docs:
4964
+ - {path: docs/application-stacks.md#r300, editions: [lite, full]}
4965
+ exemplifiedBy:
4966
+ - {path: packages/hfs/templates/app/skeleton-lite/.starcistacks, edition: lite}
4967
+ - {path: packages/hfs/templates/app/skeleton/.starcistacks, edition: full}
4968
+ specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
4969
+ witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): external smoke fixtures", date: "2026-10-17"}
@@ -1,3 +1,13 @@
1
+ APP_SECRET_IN_CI:
2
+ title: "App runtime secret appears in CI custody"
3
+ title_vi: "Bí mật ứng dụng xuất hiện trong CI"
4
+ meaning_vi: "Khóa cấp cho container ứng dụng cũng được khai báo hoặc tìm thấy trong kho CI."
5
+ causes_vi:
6
+ - "Khóa cấp cho container ứng dụng cũng được khai báo hoặc tìm thấy trong kho CI."
7
+ nextStep_vi: "Giữ khóa ứng dụng trong .enc và xóa khai báo hoặc bản sao CI sau khi kiểm tra nơi dùng."
8
+ owner: op-retry
9
+ kind: check-finding
10
+
1
11
  ARCH_COMPILER_FAILURE:
2
12
  title: "Compiler failed during architecture check"
3
13
  title_vi: "Trình biên dịch lỗi khi kiểm kiến trúc"
@@ -1671,6 +1681,26 @@ BE_WEBHOOK_UNVERIFIED:
1671
1681
  owner: op-retry
1672
1682
  kind: check-finding
1673
1683
 
1684
+ CI_DECLARATION_DRIFT:
1685
+ title: "Workflow references drift from CI declarations"
1686
+ title_vi: "Workflow lệch khai báo CI"
1687
+ meaning_vi: "Workflow hoặc liên kết dịch vụ thiếu khai báo đúng lớp, hoặc khai báo bắt buộc không được dùng."
1688
+ causes_vi:
1689
+ - "Workflow hoặc liên kết dịch vụ thiếu khai báo đúng lớp, hoặc khai báo bắt buộc không được dùng."
1690
+ nextStep_vi: "Đối chiếu secrets và vars trong workflow với ci và liên kết dịch vụ; chỉ đánh dấu optional khi phù hợp."
1691
+ owner: op-retry
1692
+ kind: check-finding
1693
+
1694
+ CI_SECRET_SEALED:
1695
+ title: "CI name overlaps sealed app custody"
1696
+ title_vi: "Tên CI trùng khóa bí mật đã niêm phong"
1697
+ meaning_vi: "Tên CI hoặc Dependabot cũng là khóa trong thành viên .enc của ứng dụng."
1698
+ causes_vi:
1699
+ - "Tên CI hoặc Dependabot cũng là khóa trong thành viên .enc của ứng dụng."
1700
+ nextStep_vi: "Bỏ khóa ứng dụng khỏi khai báo CI; đưa bí mật CI vào kho GitHub tương ứng."
1701
+ owner: op-retry
1702
+ kind: check-finding
1703
+
1674
1704
  CI_TRIGGERS_RELEASE_ONLY:
1675
1705
  title: "Workflow trigger other than a release tag, a person or the runtime's main"
1676
1706
  title_vi: "Workflow có trigger không phải tag phát hành, người chạy tay hay main của runtime"
@@ -2470,6 +2500,16 @@ FE_PROPS_MUTABLE:
2470
2500
  owner: op-retry
2471
2501
  kind: check-finding
2472
2502
 
2503
+ FE_PUBLIC_BUILD_ARG_MISSING:
2504
+ title: "Required public front-end build arguments are missing"
2505
+ title_vi: "Thiếu tham số build công khai bắt buộc của front end"
2506
+ meaning_vi: "Dockerfile thiếu giá trị mặc định ARG và ảnh triển khai thiếu tên NEXT_PUBLIC bắt buộc trong môi trường được báo."
2507
+ causes_vi:
2508
+ - "Vi phạm R300: mã nguồn, cấu hình hoặc schema yêu cầu giá trị công khai nhưng ảnh triển khai không cung cấp tên đó."
2509
+ nextStep_vi: "Thêm giá trị mặc định ARG trong Dockerfile hoặc buildArgs.values hay buildArgs.sealed.keys cho ảnh trong mọi môi trường triển khai; chỉ kiểm tra tên, không mở giá trị mã hóa."
2510
+ owner: op-retry
2511
+ kind: check-finding
2512
+
2473
2513
  FE_PURE_REACHES_DATA:
2474
2514
  title: "Pure component reaches hooks or API"
2475
2515
  title_vi: "Thành phần thuần chạm tới hook hoặc API"
@@ -3308,6 +3348,16 @@ HFS_EDITION_INVALID:
3308
3348
  owner: op-retry
3309
3349
  kind: check-finding
3310
3350
 
3351
+ HFS_EMIT_DB_TYPES_STALE:
3352
+ title: "Database types require current migration history"
3353
+ title_vi: "Lịch sử migration chưa khớp để sinh kiểu"
3354
+ meaning_vi: "Tập phiên bản đã áp dụng trong DB cục bộ khác dấu thời gian tệp supabase/migrations."
3355
+ causes_vi:
3356
+ - "Tập phiên bản đã áp dụng trong DB cục bộ khác dấu thời gian tệp supabase/migrations."
3357
+ nextStep_vi: "Chạy npm run db:reset rồi starci app emit; kiểm tra cả phiên bản thiếu và phiên bản thừa."
3358
+ owner: op-retry
3359
+ kind: verb-refusal
3360
+
3311
3361
  HFS_EMPTY_DIR:
3312
3362
  title: "No empty directory outside an `ignored` slot"
3313
3363
  title_vi: "Thư mục rỗng còn sót lại"
@@ -4109,6 +4159,16 @@ HFS_UNUSED_SYMBOL:
4109
4159
  owner: op-retry
4110
4160
  kind: check-finding
4111
4161
 
4162
+ HFS_WORKFLOW_CONTEXT:
4163
+ title: "Workflow expressions use contexts available at their key"
4164
+ title_vi: "Biểu thức workflow dùng ngữ cảnh không được phép"
4165
+ meaning_vi: "Biểu thức tại file:line và đường dẫn khóa dùng ngữ cảnh chưa có tại khóa đó."
4166
+ causes_vi:
4167
+ - "Vi phạm R299: env cấp job đọc runner, job, steps hoặc env trước khi ngữ cảnh sẵn sàng."
4168
+ nextStep_vi: "Chuyển env phụ thuộc runner vào env của bước sử dụng, hoặc dùng RUNNER_TEMP trong shell; kiểm tra file:line và đường dẫn khóa được báo."
4169
+ owner: op-retry
4170
+ kind: check-finding
4171
+
4112
4172
  HFS_WORKFLOW_PIN:
4113
4173
  title: "Remote workflow actions use immutable commit SHAs"
4114
4174
  title_vi: "Action của workflow chưa được ghim SHA"
@@ -70,7 +70,7 @@ properties:
70
70
  description: Release gates of the app (starci app release gate and push); packages/hfs/release/gate.mjs is the authority for the fields.
71
71
  type: object
72
72
  database:
73
- description: Database cutover data (starci app db migrate and post-cutover); packages/hfs/db/migrate.mjs is the authority for the fields.
73
+ description: 'Database cutover data (starci app db migrate and post-cutover); packages/hfs/db/migrate.mjs is the authority for the fields. reset: optional mapping with only backupMaxAgeHours (finite positive number; default 24 hours).'
74
74
  type: object
75
75
  jobs:
76
76
  description: Application-owned schedules, bound to their back-end CLI commands.
@@ -104,6 +104,7 @@ properties:
104
104
  properties:
105
105
  status: {enum: [deferred, supported]}
106
106
  reason: {type: string, minLength: 1}
107
+ ci: {$ref: '#/$defs/ciDeclaration'}
107
108
  services:
108
109
  description: >-
109
110
  The delivery, quality and platform services this repository's code and CI use - NOT Compose
@@ -119,6 +120,9 @@ properties:
119
120
  additionalProperties: false
120
121
  properties:
121
122
  sonar: {$ref: '#/$defs/service'}
123
+ codecov: {$ref: '#/$defs/service'}
124
+ dependabot: {$ref: '#/$defs/serviceOptionalCi'}
125
+ audit: {$ref: '#/$defs/serviceOptionalCi'}
122
126
  container-registry: {$ref: '#/$defs/service'}
123
127
  analytics: {$ref: '#/$defs/service'}
124
128
  error-tracking: {$ref: '#/$defs/service'}
@@ -140,6 +144,31 @@ $defs:
140
144
  local - a server a stack runs (stack and host.local required); hosted - a SaaS or remote
141
145
  server (host.public required); disabled - not used (reason required, CI must not call it).
142
146
  enum: [local, hosted, disabled]
147
+ organization: {type: string, minLength: 1}
148
+ flag: {type: string, minLength: 1}
149
+ target: {type: number, minimum: 0, maximum: 100}
150
+ components: {enum: [auto]}
151
+ required: {type: boolean}
152
+ ecosystems: {type: array, items: {enum: [npm, docker, github-actions]}}
153
+ schedule:
154
+ type: object
155
+ additionalProperties: false
156
+ required: [interval]
157
+ properties:
158
+ interval: {enum: [daily, weekly, monthly]}
159
+ day: {enum: [monday, tuesday, wednesday, thursday, friday, saturday, sunday]}
160
+ time: {type: string, pattern: '^(?:[01][0-9]|2[0-3]):[0-5][0-9]$'}
161
+ groups:
162
+ type: object
163
+ additionalProperties: false
164
+ properties:
165
+ minorPatch: {enum: [grouped]}
166
+ major: {enum: [per-package]}
167
+ ignore: {type: array, items: {type: string}}
168
+ security: {enum: [immediate]}
169
+ level: {enum: [low, moderate, high, critical]}
170
+ omitDev: {type: boolean}
171
+ in: {type: array, items: {enum: [release-gate, ci]}}
143
172
  purpose: {type: string, minLength: 1}
144
173
  reason: {type: string, minLength: 1}
145
174
  qualityGate:
@@ -200,6 +229,104 @@ $defs:
200
229
  properties:
201
230
  needed: {type: string, minLength: 1}
202
231
  reason: {type: string, minLength: 1}
232
+ serviceOptionalCi:
233
+ type: object
234
+ additionalProperties: false
235
+ required: [provider, mode, ownerAction]
236
+ properties:
237
+ provider: {$ref: '#/$defs/service/properties/provider'}
238
+ mode: {$ref: '#/$defs/service/properties/mode'}
239
+ organization: {$ref: '#/$defs/service/properties/organization'}
240
+ target: {$ref: '#/$defs/service/properties/target'}
241
+ components: {$ref: '#/$defs/service/properties/components'}
242
+ required: {$ref: '#/$defs/service/properties/required'}
243
+ ecosystems: {$ref: '#/$defs/service/properties/ecosystems'}
244
+ schedule: {$ref: '#/$defs/service/properties/schedule'}
245
+ groups: {$ref: '#/$defs/service/properties/groups'}
246
+ ignore: {$ref: '#/$defs/service/properties/ignore'}
247
+ security: {$ref: '#/$defs/service/properties/security'}
248
+ level: {$ref: '#/$defs/service/properties/level'}
249
+ omitDev: {$ref: '#/$defs/service/properties/omitDev'}
250
+ in: {$ref: '#/$defs/service/properties/in'}
251
+ purpose: {$ref: '#/$defs/service/properties/purpose'}
252
+ reason: {$ref: '#/$defs/service/properties/reason'}
253
+ qualityGate: {$ref: '#/$defs/service/properties/qualityGate'}
254
+ host: {$ref: '#/$defs/service/properties/host'}
255
+ stack: {$ref: '#/$defs/service/properties/stack'}
256
+ auth: {$ref: '#/$defs/service/properties/auth'}
257
+ projects: {$ref: '#/$defs/service/properties/projects'}
258
+ credentials: {$ref: '#/$defs/service/properties/credentials'}
259
+ runtimeSecrets: {$ref: '#/$defs/service/properties/runtimeSecrets'}
260
+ ci: {$ref: '#/$defs/service/properties/ci'}
261
+ ownerAction: {$ref: '#/$defs/service/properties/ownerAction'}
262
+ ciName: {type: string, pattern: '^[A-Z][A-Z0-9_]*$'}
263
+ ciDeclaration:
264
+ type: object
265
+ additionalProperties: false
266
+ properties:
267
+ github:
268
+ type: object
269
+ additionalProperties: false
270
+ required: [repository]
271
+ properties:
272
+ repository: {type: string, pattern: '^[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+$'}
273
+ defaultBranch: {type: string, minLength: 1, default: main}
274
+ workflow: {type: string, pattern: '^[A-Za-z0-9_.-]+\.ya?ml$', default: ci.yml}
275
+ secrets: {type: array, items: {$ref: '#/$defs/ciSecret'}}
276
+ vars: {type: array, items: {$ref: '#/$defs/ciVariable'}}
277
+ dependabot:
278
+ type: object
279
+ additionalProperties: false
280
+ properties:
281
+ secrets:
282
+ type: array
283
+ items:
284
+ type: object
285
+ additionalProperties: false
286
+ required: [name]
287
+ properties:
288
+ name: {$ref: '#/$defs/ciName'}
289
+ purpose: {type: string}
290
+ ciSecret:
291
+ anyOf:
292
+ - type: object
293
+ additionalProperties: false
294
+ required: [name, scope]
295
+ properties:
296
+ name: {$ref: '#/$defs/ciName'}
297
+ scope: {const: repository}
298
+ purpose: {type: string}
299
+ optional: {type: boolean}
300
+ - type: object
301
+ additionalProperties: false
302
+ required: [name, scope, environment]
303
+ properties:
304
+ name: {$ref: '#/$defs/ciName'}
305
+ scope: {const: environment}
306
+ environment: {type: string, pattern: '^[a-z][a-z0-9-]*$'}
307
+ purpose: {type: string}
308
+ optional: {type: boolean}
309
+ ciVariable:
310
+ anyOf:
311
+ - type: object
312
+ additionalProperties: false
313
+ required: [name, scope, value]
314
+ properties:
315
+ name: {$ref: '#/$defs/ciName'}
316
+ scope: {const: repository}
317
+ value: {type: string}
318
+ purpose: {type: string}
319
+ optional: {type: boolean}
320
+ - type: object
321
+ additionalProperties: false
322
+ required: [name, scope, value, environment]
323
+ properties:
324
+ name: {$ref: '#/$defs/ciName'}
325
+ scope: {const: environment}
326
+ environment: {type: string, pattern: '^[a-z][a-z0-9-]*$'}
327
+ value: {type: string}
328
+ purpose: {type: string}
329
+ optional: {type: boolean}
203
330
  serviceStack:
204
331
  description: >-
205
332
  Which stack defines a local service - either a project-owned .starcistacks stack
@@ -269,6 +396,9 @@ $defs:
269
396
  additionalProperties: false
270
397
  required: [wiring]
271
398
  properties:
399
+ token: {$ref: '#/$defs/ciName'}
400
+ hostVar: {$ref: '#/$defs/ciName'}
401
+ organizationVar: {$ref: '#/$defs/ciName'}
272
402
  wiring: {enum: [required, optional-follow-up, not-used]}
273
403
  workflow: {type: string, minLength: 1}
274
404
  permissions: {type: array, items: {type: string, minLength: 1}}