code-foundry 0.4.0 → 0.6.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.
@@ -7,6 +7,7 @@ profile="${REPO_FOUNDRY_PROFILE:-auto}"
7
7
  protection=false
8
8
  dry_run=false
9
9
  prune=false
10
+ force=false
10
11
  languages="${REPO_FOUNDRY_LANGUAGES:-auto}"
11
12
  features="${REPO_FOUNDRY_FEATURES:-all}"
12
13
  package_manager="${REPO_FOUNDRY_PACKAGE_MANAGER:-auto}"
@@ -41,6 +42,7 @@ Options:
41
42
  --license-file PATH Use an exact custom license file
42
43
  --npm-publish Enable npm publication in the release workflow
43
44
  --dry-run Preview changes without writing files
45
+ --force Replace protected standard docs/templates
44
46
  --prune Remove disabled standard workflows (never custom workflows)
45
47
  --protection Synchronize main branch required checks
46
48
  --no-bootstrap Skip mise/hooks/doctor bootstrap after init
@@ -66,6 +68,7 @@ while [ "$#" -gt 0 ]; do
66
68
  --license-file) license_file="${2:?missing license file}"; shift 2 ;;
67
69
  --npm-publish) npm_publish=true; shift ;;
68
70
  --dry-run) dry_run=true; shift ;;
71
+ --force) force=true; shift ;;
69
72
  --prune) prune=true; shift ;;
70
73
  --protection) protection=true; shift ;;
71
74
  --no-bootstrap) bootstrap=false; shift ;;
@@ -110,6 +113,7 @@ sync_args=(
110
113
  if [ -n "$license_file" ]; then sync_args+=(--license-file "$license_file"); fi
111
114
  if [ "$dry_run" = true ]; then sync_args+=(--check); else sync_args+=(--apply); fi
112
115
  if [ "$prune" = true ]; then sync_args+=(--prune); fi
116
+ if [ "$force" = true ]; then sync_args+=(--force); fi
113
117
  bash "$sync_script" "${sync_args[@]}"
114
118
 
115
119
  if [ "$dry_run" = true ]; then
@@ -18,6 +18,7 @@ Options:
18
18
  --check Preview changes (default)
19
19
  --apply Apply changes
20
20
  --prune Remove disabled standard workflows
21
+ --force Replace protected standard docs/templates
21
22
  EOF
22
23
  }
23
24
 
@@ -29,6 +30,7 @@ profile="${REPO_FOUNDRY_PROFILE:-auto}"
29
30
  languages="${REPO_FOUNDRY_LANGUAGES:-auto}"
30
31
  features="${REPO_FOUNDRY_FEATURES:-all}"
31
32
  prune=false
33
+ force=false
32
34
  languages_set=false
33
35
  profile_set=false
34
36
  features_set=false
@@ -107,6 +109,7 @@ while [ "$#" -gt 0 ]; do
107
109
  --check) mode="check"; shift ;;
108
110
  --apply) mode="apply"; shift ;;
109
111
  --prune) prune=true; shift ;;
112
+ --force) force=true; shift ;;
110
113
  -h|--help) usage; exit 0 ;;
111
114
  *) usage >&2; exit 2 ;;
112
115
  esac
@@ -270,6 +273,14 @@ standard_workflow() {
270
273
  esac
271
274
  }
272
275
 
276
+ protected_standard_file() {
277
+ case "$1" in
278
+ AGENTS.md|.github/CODE_OF_CONDUCT.md|.github/CONTRIBUTING.md|.github/PULL_REQUEST_TEMPLATE.md|.github/SECURITY.md|.github/ISSUE_TEMPLATE/*)
279
+ return 0 ;;
280
+ *) return 1 ;;
281
+ esac
282
+ }
283
+
273
284
  custom_workflows=()
274
285
  if [ -d .github/workflows ]; then
275
286
  while IFS= read -r workflow; do
@@ -294,6 +305,10 @@ for file in "${files[@]}"; do
294
305
  echo "Template file missing: $file" >&2
295
306
  exit 1
296
307
  fi
308
+ if [ "$force" != true ] && [ -f "$file" ] && protected_standard_file "$file"; then
309
+ printf 'Preserving existing authored file %s (use --force to refresh).\n' "$file"
310
+ continue
311
+ fi
297
312
  if { [ "$file" = LICENSE ] || [ "$file" = NOTICE ]; } && [ "$license" = preserve ] && [ -f "$file" ]; then
298
313
  continue
299
314
  fi
@@ -0,0 +1,179 @@
1
+ name: Code Foundry CI
2
+
3
+ on:
4
+ workflow_call:
5
+ inputs:
6
+ runtime-repository:
7
+ description: Repository containing the Code Foundry runtime.
8
+ required: false
9
+ type: string
10
+ default: 0xPlayerOne/code-foundry
11
+ runtime-ref:
12
+ description: Code Foundry runtime tag or ref.
13
+ required: false
14
+ type: string
15
+ default: v0.5.0
16
+
17
+ permissions:
18
+ contents: read
19
+
20
+ env:
21
+ TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
22
+ TURBO_TEAM: ${{ vars.TURBO_TEAM }}
23
+ REPO_FOUNDRY_PROFILE: ${{ vars.REPO_FOUNDRY_PROFILE }}
24
+ REPO_FOUNDRY_LANGUAGES: ${{ vars.REPO_FOUNDRY_LANGUAGES }}
25
+ REPO_FOUNDRY_FEATURES: ${{ vars.REPO_FOUNDRY_FEATURES }}
26
+ REPO_FOUNDRY_PACKAGE_MANAGER: ${{ vars.REPO_FOUNDRY_PACKAGE_MANAGER }}
27
+ REPO_FOUNDRY_RUNNER: ${{ vars.REPO_FOUNDRY_RUNNER }}
28
+ REPO_FOUNDRY_CACHE_PACKAGES: ${{ vars.REPO_FOUNDRY_CACHE_PACKAGES || 'auto' }}
29
+ REPO_FOUNDRY_CACHE_BUILD: ${{ vars.REPO_FOUNDRY_CACHE_BUILD || 'auto' }}
30
+ REPO_FOUNDRY_BASE_SHA: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event.before || '' }}
31
+
32
+ concurrency:
33
+ group: ${{ github.workflow }}-${{ github.event.pull_request.head.repo.full_name || github.repository }}-${{ github.event.pull_request.head.ref || github.ref_name }}
34
+ cancel-in-progress: true
35
+
36
+ jobs:
37
+ format:
38
+ name: Format
39
+ runs-on: ubuntu-latest
40
+ steps:
41
+ - name: Checkout
42
+ uses: actions/checkout@v7
43
+ - name: Runtime
44
+ uses: actions/checkout@v7
45
+ with:
46
+ repository: ${{ inputs.runtime-repository }}
47
+ ref: ${{ inputs.runtime-ref }}
48
+ path: .code-foundry
49
+ sparse-checkout: |
50
+ .github/actions
51
+ .github/scripts
52
+ - name: Install runtime
53
+ run: |
54
+ mkdir -p .github/actions .github/scripts
55
+ cp -R .code-foundry/.github/actions/. .github/actions/
56
+ cp -R .code-foundry/.github/scripts/. .github/scripts/
57
+ - name: Detect
58
+ id: applicability
59
+ run: bash .github/scripts/ci.sh should_run format >> "$GITHUB_OUTPUT"
60
+ - name: Fast path
61
+ if: steps.applicability.outputs.applicable == 'true'
62
+ run: bash .github/scripts/format-fast-path.sh
63
+ - name: Setup
64
+ if: steps.applicability.outputs.applicable == 'true'
65
+ uses: ./.github/actions/setup
66
+ with:
67
+ install: 'false'
68
+ cache-format: 'true'
69
+ cache-lint: 'false'
70
+ cache-build: 'false'
71
+ task: format
72
+ task-javascript: 'true'
73
+ task-python: 'false'
74
+ task-rust: 'false'
75
+ - name: Format
76
+ if: steps.applicability.outputs.applicable == 'true'
77
+ run: bash .github/scripts/ci.sh format
78
+
79
+ lint:
80
+ name: Lint
81
+ runs-on: ubuntu-latest
82
+ steps:
83
+ - name: Checkout
84
+ uses: actions/checkout@v7
85
+ - name: Runtime
86
+ uses: actions/checkout@v7
87
+ with:
88
+ repository: ${{ inputs.runtime-repository }}
89
+ ref: ${{ inputs.runtime-ref }}
90
+ path: .code-foundry
91
+ sparse-checkout: |
92
+ .github/actions
93
+ .github/scripts
94
+ - name: Install runtime
95
+ run: |
96
+ mkdir -p .github/actions .github/scripts
97
+ cp -R .code-foundry/.github/actions/. .github/actions/
98
+ cp -R .code-foundry/.github/scripts/. .github/scripts/
99
+ - name: Detect
100
+ id: applicability
101
+ run: bash .github/scripts/ci.sh should_run lint >> "$GITHUB_OUTPUT"
102
+ - name: Setup
103
+ if: steps.applicability.outputs.applicable == 'true'
104
+ uses: ./.github/actions/setup
105
+ with:
106
+ install: 'true'
107
+ cache-lint: 'true'
108
+ task: lint
109
+ - name: Lint
110
+ if: steps.applicability.outputs.applicable == 'true'
111
+ run: bash .github/scripts/ci.sh lint
112
+
113
+ type-check:
114
+ name: Type-Check
115
+ runs-on: ubuntu-latest
116
+ steps:
117
+ - name: Checkout
118
+ uses: actions/checkout@v7
119
+ - name: Runtime
120
+ uses: actions/checkout@v7
121
+ with:
122
+ repository: ${{ inputs.runtime-repository }}
123
+ ref: ${{ inputs.runtime-ref }}
124
+ path: .code-foundry
125
+ sparse-checkout: |
126
+ .github/actions
127
+ .github/scripts
128
+ - name: Install runtime
129
+ run: |
130
+ mkdir -p .github/actions .github/scripts
131
+ cp -R .code-foundry/.github/actions/. .github/actions/
132
+ cp -R .code-foundry/.github/scripts/. .github/scripts/
133
+ - name: Detect
134
+ id: applicability
135
+ run: bash .github/scripts/ci.sh should_run type_check >> "$GITHUB_OUTPUT"
136
+ - name: Setup
137
+ if: steps.applicability.outputs.applicable == 'true'
138
+ uses: ./.github/actions/setup
139
+ with:
140
+ install: 'true'
141
+ cache-build: 'true'
142
+ task: type_check
143
+ - name: Type-Check
144
+ if: steps.applicability.outputs.applicable == 'true'
145
+ run: bash .github/scripts/ci.sh type_check
146
+
147
+ build:
148
+ name: Build
149
+ runs-on: ubuntu-latest
150
+ steps:
151
+ - name: Checkout
152
+ uses: actions/checkout@v7
153
+ - name: Runtime
154
+ uses: actions/checkout@v7
155
+ with:
156
+ repository: ${{ inputs.runtime-repository }}
157
+ ref: ${{ inputs.runtime-ref }}
158
+ path: .code-foundry
159
+ sparse-checkout: |
160
+ .github/actions
161
+ .github/scripts
162
+ - name: Install runtime
163
+ run: |
164
+ mkdir -p .github/actions .github/scripts
165
+ cp -R .code-foundry/.github/actions/. .github/actions/
166
+ cp -R .code-foundry/.github/scripts/. .github/scripts/
167
+ - name: Detect
168
+ id: applicability
169
+ run: bash .github/scripts/ci.sh should_run build >> "$GITHUB_OUTPUT"
170
+ - name: Setup
171
+ if: steps.applicability.outputs.applicable == 'true'
172
+ uses: ./.github/actions/setup
173
+ with:
174
+ install: 'true'
175
+ cache-build: 'true'
176
+ task: build
177
+ - name: Build
178
+ if: steps.applicability.outputs.applicable == 'true'
179
+ run: bash .github/scripts/ci.sh build
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.6.0](https://github.com/0xPlayerOne/code-foundry/compare/v0.5.0...v0.6.0) (2026-07-28)
4
+
5
+
6
+ ### Features
7
+
8
+ * **ci:** add reusable workflow runtime ([4900da5](https://github.com/0xPlayerOne/code-foundry/commit/4900da5e6141015146c4be2059bbce7da0c25f5d))
9
+
10
+ ## [0.5.0](https://github.com/0xPlayerOne/code-foundry/compare/v0.4.0...v0.5.0) (2026-07-28)
11
+
12
+
13
+ ### Features
14
+
15
+ * **init:** preserve authored repository docs ([9fab688](https://github.com/0xPlayerOne/code-foundry/commit/9fab6880ad82762cf4e2eb7d813355ab22cdb905))
16
+
3
17
  ## [0.4.0](https://github.com/0xPlayerOne/code-foundry/compare/v0.3.0...v0.4.0) (2026-07-28)
4
18
 
5
19
 
package/README.md CHANGED
@@ -65,6 +65,10 @@ Use `bash .github/scripts/sync-template.sh --source ... --check` to preview diff
65
65
 
66
66
  The initializer is intentionally flag-driven so the same baseline can be used as a small repository package. Language selection controls CodeQL and records the repository profile; feature selection controls which standard workflows are installed. `auto` detects supported languages, while `all` enables every standard workflow. The resolver profiles the repository for language, package manager, project shape, release type, runners, and cache policy.
67
67
 
68
+ Existing authored documentation and issue/PR templates are preserved by
69
+ default. Pass `--force` when intentionally refreshing those files from the
70
+ baseline; repository-specific workflows and application files remain protected.
71
+
68
72
  ```bash
69
73
  # Preview a TypeScript + Python repository without changing files
70
74
  bash .github/scripts/init-repo.sh \
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "code-foundry",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "description": "A fast, language-aware repository factory for agent-ready workflows, testing, security, and release automation.",
5
5
  "type": "module",
6
6
  "license": "AGPL-3.0-or-later",
package/src/cli.mjs CHANGED
@@ -27,6 +27,7 @@ Init/sync options:
27
27
  --license-file PATH Use an exact custom license file
28
28
  --npm-publish Enable npm publication in the release workflow
29
29
  --dry-run Preview changes without writing files
30
+ --force Replace protected standard docs/templates
30
31
  --prune Remove disabled standard workflows
31
32
  --protection Synchronize main branch protections (init only)
32
33
  --no-bootstrap Skip mise/hooks/doctor bootstrap after init
@@ -56,6 +57,7 @@ function parseArgs(argv) {
56
57
  featuresSet: false,
57
58
  dryRun: false,
58
59
  prune: false,
60
+ force: false,
59
61
  protection: false,
60
62
  bootstrap: true,
61
63
  }
@@ -87,6 +89,7 @@ function parseArgs(argv) {
87
89
  continue
88
90
  }
89
91
  if (arg === '--dry-run') options.dryRun = true
92
+ else if (arg === '--force') options.force = true
90
93
  else if (arg === '--prune') options.prune = true
91
94
  else if (arg === '--protection') options.protection = true
92
95
  else if (arg === '--no-bootstrap') options.bootstrap = false
@@ -118,6 +121,7 @@ function main() {
118
121
  if (options.languagesSet) common.push('--languages', options.languages)
119
122
  if (options.featuresSet) common.push('--features', options.features)
120
123
  if (options.prune) common.push('--prune')
124
+ if (options.force) common.push('--force')
121
125
  if (options.dryRun) common.push('--check')
122
126
  else common.push('--apply')
123
127
 
@@ -136,6 +140,7 @@ function main() {
136
140
  if (options.protection) initArgs.push('--protection')
137
141
  if (options.dryRun) initArgs.push('--dry-run')
138
142
  if (options.prune) initArgs.push('--prune')
143
+ if (options.force) initArgs.push('--force')
139
144
  if (options.npmPublish) initArgs.push('--npm-publish')
140
145
  if (!options.bootstrap) initArgs.push('--no-bootstrap')
141
146
  run('init-repo.sh', initArgs, target)