code-foundry 0.32.4 → 0.33.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/.github/CONTRIBUTING.md +17 -14
- package/.github/workflows/ci.yml +25 -8
- package/.github/workflows/codeql.yml +28 -14
- package/.github/workflows/draft-pr.yml +25 -18
- package/.github/workflows/draft-pr_self-ci.yml +3 -1
- package/.github/workflows/opencode-security_self-ci.yml +4 -2
- package/.github/workflows/release-pr.yml +31 -9
- package/.github/workflows/release-pr_self-ci.yml +4 -7
- package/.github/workflows/release.yml +136 -23
- package/.github/workflows/release_self-ci.yml +5 -1
- package/.github/workflows/security.yml +18 -11
- package/.github/workflows/test.yml +28 -9
- package/.github/workflows/validation.yml +183 -0
- package/.github/workflows/validation_self-ci.yml +82 -0
- package/CHANGELOG.md +12 -0
- package/README.md +7 -4
- package/docs/CONFIGURATION.md +2 -1
- package/docs/RELEASES.md +26 -18
- package/docs/WORKFLOWS.md +54 -4
- package/package.json +1 -1
- package/src/commands/doctor.mjs +53 -3
- package/src/commands/release.mjs +220 -68
- package/src/commands/sync.mjs +88 -4
- package/src/lib/github-doctor.mjs +10 -4
- package/src/lib/release-policy.mjs +88 -19
- package/src/lib/validation-policy.mjs +127 -0
- package/src/runtime.mjs +54 -0
- package/.github/workflows/ci_self-ci.yml +0 -21
- package/.github/workflows/codeql_self-ci.yml +0 -29
- package/.github/workflows/security_self-ci.yml +0 -21
- package/.github/workflows/test_self-ci.yml +0 -22
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { existsSync, readFileSync } from 'node:fs'
|
|
4
4
|
import { join } from 'node:path'
|
|
5
|
+
import { isReleasePleaseHead } from './validation-policy.mjs'
|
|
5
6
|
|
|
6
7
|
const DEFAULT_RELEASE_FILES = new Set([
|
|
7
8
|
'.release-please-manifest.json',
|
|
@@ -125,6 +126,56 @@ export function validateReleasePullRequests(prs, changedPathsByPr, allowed) {
|
|
|
125
126
|
return { valid: errors.length === 0, generated, errors }
|
|
126
127
|
}
|
|
127
128
|
|
|
129
|
+
/** Files that must change for a generated release PR to count as a version bump. */
|
|
130
|
+
const VERSION_METADATA_FILES = new Set([
|
|
131
|
+
'.release-please-manifest.json',
|
|
132
|
+
'package.json',
|
|
133
|
+
'Cargo.toml',
|
|
134
|
+
'pyproject.toml',
|
|
135
|
+
'version.txt',
|
|
136
|
+
])
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Strict diff and version policy for the release validation tier. The head
|
|
140
|
+
* must carry the exact approved Release Please prefix, come from the same
|
|
141
|
+
* repository, change at least one path, change no unexpected paths, and bump
|
|
142
|
+
* at least one version-metadata file (or a declared extra file).
|
|
143
|
+
* @param {{ headRef?: string, headRepo?: string, repository?: string, changedPaths?: string[], config?: Record<string, unknown> }} input
|
|
144
|
+
* @returns {{ valid: boolean, errors: string[], changedPaths: string[] }}
|
|
145
|
+
*/
|
|
146
|
+
export function validateGeneratedReleaseDiff(input) {
|
|
147
|
+
const { headRef = '', headRepo = '', repository = '', changedPaths = [], config = {} } = input
|
|
148
|
+
/** @type {string[]} */
|
|
149
|
+
const errors = []
|
|
150
|
+
if (!isReleasePleaseHead(headRef)) {
|
|
151
|
+
errors.push(`Head branch ${headRef || '(missing)'} is not a generated Release Please branch.`)
|
|
152
|
+
}
|
|
153
|
+
if (!repository || !headRepo) {
|
|
154
|
+
errors.push('Generated release validation requires both the head and base repository identities.')
|
|
155
|
+
} else if (headRepo !== repository) {
|
|
156
|
+
errors.push(`Head repository ${headRepo} is not ${repository}; generated release validation requires a same-repository pull request.`)
|
|
157
|
+
}
|
|
158
|
+
const paths = [...new Set(changedPaths.map((path) => String(path).trim()).filter(Boolean))]
|
|
159
|
+
if (!paths.length) errors.push('Generated release pull request has no changed files.')
|
|
160
|
+
const unexpected = unexpectedReleasePaths(paths, approvedReleaseFiles(config))
|
|
161
|
+
if (unexpected.length) errors.push(`Generated release pull request contains unexpected paths: ${unexpected.join(', ')}`)
|
|
162
|
+
const versionMetadata = new Set(VERSION_METADATA_FILES)
|
|
163
|
+
addExtraFiles(versionMetadata, config['extra-files'])
|
|
164
|
+
const packages = config.packages
|
|
165
|
+
if (packages && typeof packages === 'object' && !Array.isArray(packages)) {
|
|
166
|
+
for (const [directory, value] of Object.entries(packages)) {
|
|
167
|
+
const prefix = directory === '.' ? '' : directory.replace(/\/$/, '')
|
|
168
|
+
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
169
|
+
addExtraFiles(versionMetadata, value['extra-files'], prefix)
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
if (!paths.some((path) => versionMetadata.has(path))) {
|
|
174
|
+
errors.push('Generated release pull request changes no version metadata.')
|
|
175
|
+
}
|
|
176
|
+
return { valid: errors.length === 0, errors, changedPaths: paths }
|
|
177
|
+
}
|
|
178
|
+
|
|
128
179
|
/**
|
|
129
180
|
* Build a non-destructive release recovery plan from independent release
|
|
130
181
|
* metadata sources.
|
|
@@ -166,41 +217,59 @@ function compareVersions(a, b) {
|
|
|
166
217
|
}
|
|
167
218
|
|
|
168
219
|
/**
|
|
169
|
-
* Classify the relationship between main and staging
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
* @param {{
|
|
220
|
+
* Classify the relationship between main and staging using commit-level divergence.
|
|
221
|
+
* Any non-release main-only commit fails. Any staging-only commit triggers a replay
|
|
222
|
+
* path so no staging-only work can be silently discarded.
|
|
223
|
+
* @param {{
|
|
224
|
+
* mainSha: string,
|
|
225
|
+
* stagingSha: string,
|
|
226
|
+
* mainOnlyCommits?: Array<{ sha?: string, changedPaths?: string[] }>,
|
|
227
|
+
* stagingOnlyCommits?: Array<{ sha?: string, changedPaths?: string[] }>,
|
|
228
|
+
* allowed?: Set<string>,
|
|
229
|
+
* }} input
|
|
173
230
|
*/
|
|
174
231
|
export function classifyReconciliation(input) {
|
|
175
232
|
const {
|
|
176
233
|
mainSha,
|
|
177
234
|
stagingSha,
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
stagingChangedPaths = [],
|
|
235
|
+
mainOnlyCommits = [],
|
|
236
|
+
stagingOnlyCommits = [],
|
|
181
237
|
allowed = approvedReleaseFiles(),
|
|
182
238
|
} = input
|
|
183
239
|
if (!mainSha || !stagingSha) return { action: 'fail', reason: 'Missing branch SHA.' }
|
|
184
240
|
if (mainSha === stagingSha) return { action: 'aligned', reason: 'Branches already point at the same commit.' }
|
|
185
|
-
|
|
186
|
-
|
|
241
|
+
const hasIndeterminateMainCommit = mainOnlyCommits.some((commit) => typeof commit.sha !== 'string' || !Array.isArray(commit.changedPaths))
|
|
242
|
+
if (hasIndeterminateMainCommit) return {
|
|
243
|
+
action: 'fail',
|
|
244
|
+
reason: 'Unable to inspect main-only commit metadata.',
|
|
187
245
|
}
|
|
188
|
-
|
|
189
|
-
|
|
246
|
+
const hasIndeterminateStagingCommit = stagingOnlyCommits.some((commit) => typeof commit.sha !== 'string' || !Array.isArray(commit.changedPaths))
|
|
247
|
+
if (hasIndeterminateStagingCommit) return {
|
|
248
|
+
action: 'fail',
|
|
249
|
+
reason: 'Unable to inspect staging-only commit metadata.',
|
|
190
250
|
}
|
|
191
|
-
const unexpectedMain = unexpectedReleasePaths(
|
|
192
|
-
|
|
193
|
-
|
|
251
|
+
const unexpectedMain = unexpectedReleasePaths(
|
|
252
|
+
[...new Set(mainOnlyCommits.flatMap((commit) => commit.changedPaths || []))],
|
|
253
|
+
allowed,
|
|
254
|
+
)
|
|
255
|
+
if (unexpectedMain.length) {
|
|
194
256
|
return {
|
|
195
257
|
action: 'fail',
|
|
196
|
-
reason: '
|
|
197
|
-
unexpected:
|
|
258
|
+
reason: 'main contains commits that are not release metadata.',
|
|
259
|
+
unexpected: unexpectedMain,
|
|
198
260
|
}
|
|
199
261
|
}
|
|
200
|
-
if (
|
|
201
|
-
return {
|
|
262
|
+
if (stagingOnlyCommits.length) {
|
|
263
|
+
return {
|
|
264
|
+
action: 'rebase-staging',
|
|
265
|
+
targetSha: mainSha,
|
|
266
|
+
mainOnly: mainOnlyCommits.map((commit) => commit.sha).filter(Boolean),
|
|
267
|
+
stagingOnly: stagingOnlyCommits.map((commit) => commit.sha).filter(Boolean),
|
|
268
|
+
reason: 'staging contains unpromoted commits; replay them onto main.',
|
|
269
|
+
}
|
|
202
270
|
}
|
|
203
|
-
return { action: '
|
|
271
|
+
if (mainOnlyCommits.length) return { action: 'fast-forward', targetSha: mainSha, reason: 'main only added approved release metadata.' }
|
|
272
|
+
return { action: 'aligned', targetSha: mainSha, reason: 'Branches have different history but identical content.' }
|
|
204
273
|
}
|
|
205
274
|
|
|
206
275
|
export { DEFAULT_RELEASE_FILES }
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Tiered validation policy shared by the generated validation caller, the
|
|
5
|
+
* reusable validation orchestrator, and their deterministic tests.
|
|
6
|
+
*
|
|
7
|
+
* The caller classifies every triggering event into exactly one of three
|
|
8
|
+
* fail-closed modes; the orchestrator's aggregate gate evaluates normalized
|
|
9
|
+
* job results against a mode-aware truth table. The shell steps embedded in
|
|
10
|
+
* the generated workflows are thin mirrors of these functions; keep the
|
|
11
|
+
* workflow YAML and this module in lockstep.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/** The three validation tiers. */
|
|
15
|
+
export const VALIDATION_MODES = ['fast', 'audit', 'release']
|
|
16
|
+
|
|
17
|
+
/** Exact branch prefix used by Release Please for generated version pull requests. */
|
|
18
|
+
export const RELEASE_PLEASE_PREFIX = 'release-please--branches--main'
|
|
19
|
+
|
|
20
|
+
/** Stable aggregate check name emitted by the validation orchestrator's gate job. */
|
|
21
|
+
export const AGGREGATE_CHECK_NAME = 'Validation / Gate'
|
|
22
|
+
/** Job ids owned by the validation orchestrator. */
|
|
23
|
+
export const VALIDATION_JOBS = ['ci', 'test', 'security', 'codeql', 'release-policy']
|
|
24
|
+
|
|
25
|
+
/** Events that may trigger canonical validation. */
|
|
26
|
+
export const VALIDATION_EVENTS = ['pull_request', 'schedule', 'workflow_dispatch']
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* True when the head branch is a generated Release Please version branch:
|
|
30
|
+
* either the exact prefix or the prefix followed by the `--` separator.
|
|
31
|
+
* Any other string (including prefix lookalikes without the exact boundary)
|
|
32
|
+
* is not approved.
|
|
33
|
+
* @param {unknown} headRef
|
|
34
|
+
* @returns {boolean}
|
|
35
|
+
*/
|
|
36
|
+
export function isReleasePleaseHead(headRef) {
|
|
37
|
+
if (typeof headRef !== 'string' || headRef.length === 0) return false
|
|
38
|
+
return headRef === RELEASE_PLEASE_PREFIX || headRef.startsWith(`${RELEASE_PLEASE_PREFIX}--`)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Classify an event into exactly one validation mode, failing closed:
|
|
43
|
+
* - fast: pull_request targeting staging
|
|
44
|
+
* - release: pull_request targeting main whose head is the exact approved
|
|
45
|
+
* Release Please prefix
|
|
46
|
+
* - audit: every other pull_request targeting main, plus schedule and
|
|
47
|
+
* workflow_dispatch
|
|
48
|
+
* Unsupported events (for example push) and unsupported base branches are
|
|
49
|
+
* rejected so canonical validation can never silently run or silently skip.
|
|
50
|
+
* @param {{ eventName: string, baseRef?: string, headRef?: string }} input
|
|
51
|
+
* @returns {'fast'|'audit'|'release'}
|
|
52
|
+
*/
|
|
53
|
+
export function classifyValidationMode(input) {
|
|
54
|
+
const { eventName, baseRef, headRef } = input
|
|
55
|
+
if (typeof eventName !== 'string' || !VALIDATION_EVENTS.includes(eventName)) {
|
|
56
|
+
throw new Error(
|
|
57
|
+
`Unsupported validation event: ${eventName ?? '(missing)'}; canonical validation must not run on this event.`
|
|
58
|
+
)
|
|
59
|
+
}
|
|
60
|
+
if (eventName === 'schedule' || eventName === 'workflow_dispatch') return 'audit'
|
|
61
|
+
if (typeof baseRef !== 'string' || baseRef.length === 0) {
|
|
62
|
+
throw new Error('pull_request classification requires base_ref.')
|
|
63
|
+
}
|
|
64
|
+
if (typeof headRef !== 'string' || headRef.length === 0) {
|
|
65
|
+
throw new Error('pull_request classification requires head_ref.')
|
|
66
|
+
}
|
|
67
|
+
if (baseRef === 'staging') return 'fast'
|
|
68
|
+
if (baseRef === 'main') return isReleasePleaseHead(headRef) ? 'release' : 'audit'
|
|
69
|
+
throw new Error(`Unsupported pull_request base branch: ${baseRef}; expected staging or main.`)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** @type {Record<'fast'|'audit'|'release', string[]>} */
|
|
73
|
+
const REQUIRED_JOBS_BY_MODE = {
|
|
74
|
+
fast: ['ci', 'test'],
|
|
75
|
+
audit: ['ci', 'test', 'security', 'codeql'],
|
|
76
|
+
release: ['release-policy'],
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Job ids that the aggregate gate requires for a mode. Expected skips never
|
|
81
|
+
* appear here: anything outside the returned list is not part of the gate.
|
|
82
|
+
* @param {string} mode
|
|
83
|
+
* @returns {string[]}
|
|
84
|
+
*/
|
|
85
|
+
export function requiredValidationJobs(mode) {
|
|
86
|
+
const jobs = REQUIRED_JOBS_BY_MODE[/** @type {'fast'|'audit'|'release'} */ (mode)]
|
|
87
|
+
if (!jobs) {
|
|
88
|
+
throw new Error(
|
|
89
|
+
`Unknown validation mode: ${mode ?? '(missing)'}; expected one of ${VALIDATION_MODES.join(', ')}.`
|
|
90
|
+
)
|
|
91
|
+
}
|
|
92
|
+
return [...jobs]
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Evaluate the aggregate gate for one mode against normalized job results.
|
|
97
|
+
* Only jobs required for the mode are consulted, so expected skips of
|
|
98
|
+
* non-required jobs never fail the gate. Every required job must report
|
|
99
|
+
* exactly `success`; failure, cancellation, an unexpected skip, a missing
|
|
100
|
+
* result, or an unknown result fails the gate (fail closed).
|
|
101
|
+
* @param {{ mode: string, results?: Record<string, string | null | undefined> }} input
|
|
102
|
+
* @returns {{ valid: boolean, required: string[], failures: Array<{ job: string, result: string }> }}
|
|
103
|
+
*/
|
|
104
|
+
export function evaluateValidationGate(input) {
|
|
105
|
+
const { mode, results = {} } = input
|
|
106
|
+
let required
|
|
107
|
+
try {
|
|
108
|
+
required = requiredValidationJobs(mode)
|
|
109
|
+
} catch (error) {
|
|
110
|
+
return {
|
|
111
|
+
valid: false,
|
|
112
|
+
required: [],
|
|
113
|
+
failures: [{ job: 'mode', result: error instanceof Error ? error.message : String(error) }],
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/** @type {Array<{ job: string, result: string }>} */
|
|
117
|
+
const failures = []
|
|
118
|
+
for (const job of required) {
|
|
119
|
+
const result = results[job]
|
|
120
|
+
if (result === 'success') continue
|
|
121
|
+
failures.push({
|
|
122
|
+
job,
|
|
123
|
+
result: result === undefined || result === null ? 'missing' : String(result),
|
|
124
|
+
})
|
|
125
|
+
}
|
|
126
|
+
return { valid: failures.length === 0, required, failures }
|
|
127
|
+
}
|
package/src/runtime.mjs
CHANGED
|
@@ -6,6 +6,8 @@ import { resolve } from 'node:path'
|
|
|
6
6
|
import { spawnSync } from 'node:child_process'
|
|
7
7
|
import { detectPackageManager, resolveProfile } from './lib/profile.mjs'
|
|
8
8
|
import { configured, readConfig } from './lib/config.mjs'
|
|
9
|
+
import { classifyValidationMode, evaluateValidationGate } from './lib/validation-policy.mjs'
|
|
10
|
+
import { readReleaseConfig, validateGeneratedReleaseDiff } from './lib/release-policy.mjs'
|
|
9
11
|
|
|
10
12
|
const root = process.cwd()
|
|
11
13
|
const config = readConfig(resolve(root, '.github/code-foundry.yml'))
|
|
@@ -43,6 +45,57 @@ function readPackage() {
|
|
|
43
45
|
try { return JSON.parse(readFileSync(resolve(root, 'package.json'), 'utf8')) } catch { return null }
|
|
44
46
|
}
|
|
45
47
|
|
|
48
|
+
/** @param {string} task */
|
|
49
|
+
function validation(task) {
|
|
50
|
+
if (task === 'mode') {
|
|
51
|
+
writeOutput('mode', classifyValidationMode({
|
|
52
|
+
eventName: process.env.FOUNDRY_EVENT_NAME ?? '',
|
|
53
|
+
baseRef: process.env.FOUNDRY_BASE_REF ?? '',
|
|
54
|
+
headRef: process.env.FOUNDRY_HEAD_REF ?? '',
|
|
55
|
+
}))
|
|
56
|
+
return
|
|
57
|
+
}
|
|
58
|
+
if (task === 'gate') {
|
|
59
|
+
const mode = process.env.FOUNDRY_MODE ?? ''
|
|
60
|
+
const gate = evaluateValidationGate({
|
|
61
|
+
mode,
|
|
62
|
+
results: {
|
|
63
|
+
ci: process.env.FOUNDRY_CI,
|
|
64
|
+
test: process.env.FOUNDRY_TEST,
|
|
65
|
+
security: process.env.FOUNDRY_SECURITY,
|
|
66
|
+
codeql: process.env.FOUNDRY_CODEQL,
|
|
67
|
+
'release-policy': process.env.FOUNDRY_RELEASE_POLICY,
|
|
68
|
+
},
|
|
69
|
+
})
|
|
70
|
+
if (gate.valid) {
|
|
71
|
+
console.log(`Validation gate passed for ${mode} mode.`)
|
|
72
|
+
return
|
|
73
|
+
}
|
|
74
|
+
for (const failure of gate.failures) console.error(`::error::${failure.job}: ${failure.result}`)
|
|
75
|
+
process.exitCode = 1
|
|
76
|
+
return
|
|
77
|
+
}
|
|
78
|
+
if (task === 'release_diff') {
|
|
79
|
+
const baseSha = process.env.FOUNDRY_BASE_SHA ?? ''
|
|
80
|
+
const changedPaths = baseSha ? capture('git', ['diff', '--name-only', `${baseSha}...HEAD`]).split(/\r?\n/) : []
|
|
81
|
+
const result = validateGeneratedReleaseDiff({
|
|
82
|
+
headRef: process.env.FOUNDRY_HEAD_REF ?? '',
|
|
83
|
+
headRepo: process.env.FOUNDRY_HEAD_REPO ?? '',
|
|
84
|
+
repository: process.env.FOUNDRY_REPOSITORY ?? '',
|
|
85
|
+
changedPaths,
|
|
86
|
+
config: readReleaseConfig(root),
|
|
87
|
+
})
|
|
88
|
+
if (!result.valid) {
|
|
89
|
+
for (const error of result.errors) console.error(`::error::${error}`)
|
|
90
|
+
process.exitCode = 1
|
|
91
|
+
return
|
|
92
|
+
}
|
|
93
|
+
console.log(`Release policy passed: ${result.changedPaths.length} approved changed path(s).`)
|
|
94
|
+
return
|
|
95
|
+
}
|
|
96
|
+
throw new Error(`Unknown validation task: ${task || '(missing)'}`)
|
|
97
|
+
}
|
|
98
|
+
|
|
46
99
|
/** @param {string} key @param {unknown} value */
|
|
47
100
|
function writeOutput(key, value) {
|
|
48
101
|
const line = `${key}=${typeof value === 'string' ? value : JSON.stringify(value)}\n`
|
|
@@ -347,6 +400,7 @@ try {
|
|
|
347
400
|
else if (area === 'security') security(task, ecosystem)
|
|
348
401
|
else if (area === 'codeql') codeql()
|
|
349
402
|
else if (area === 'profile') printProfile(task)
|
|
403
|
+
else if (area === 'validation') validation(task)
|
|
350
404
|
else if (area === 'pre-commit') preCommit()
|
|
351
405
|
else throw new Error(`Unknown runtime command: ${area || '(missing)'}`)
|
|
352
406
|
} catch (error) {
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
name: Code Foundry
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches: [main, staging]
|
|
6
|
-
pull_request:
|
|
7
|
-
branches: [main, staging]
|
|
8
|
-
workflow_dispatch:
|
|
9
|
-
|
|
10
|
-
permissions:
|
|
11
|
-
contents: read
|
|
12
|
-
|
|
13
|
-
jobs:
|
|
14
|
-
ci:
|
|
15
|
-
name: CI
|
|
16
|
-
uses: ./.github/workflows/ci.yml
|
|
17
|
-
with:
|
|
18
|
-
runtime-repository: 0xPlayerOne/code-foundry
|
|
19
|
-
runtime-ref: ${{ github.sha }}
|
|
20
|
-
runner: ubuntu-latest
|
|
21
|
-
secrets: inherit
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
name: Code Foundry
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches: [main, staging]
|
|
6
|
-
pull_request:
|
|
7
|
-
branches: [main, staging]
|
|
8
|
-
schedule:
|
|
9
|
-
- cron: '31 6 * * 1'
|
|
10
|
-
workflow_dispatch:
|
|
11
|
-
|
|
12
|
-
permissions:
|
|
13
|
-
actions: read
|
|
14
|
-
contents: read
|
|
15
|
-
packages: read
|
|
16
|
-
security-events: write
|
|
17
|
-
|
|
18
|
-
jobs:
|
|
19
|
-
codeql:
|
|
20
|
-
name: CodeQL
|
|
21
|
-
uses: ./.github/workflows/codeql.yml
|
|
22
|
-
with:
|
|
23
|
-
runtime-repository: 0xPlayerOne/code-foundry
|
|
24
|
-
runtime-ref: ${{ github.sha }}
|
|
25
|
-
runner: ubuntu-latest
|
|
26
|
-
rust-shards: '["all"]'
|
|
27
|
-
rust-threads: '1'
|
|
28
|
-
rust-max-parallel: 1
|
|
29
|
-
secrets: inherit
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
name: Code Foundry
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches: [main, staging]
|
|
6
|
-
pull_request:
|
|
7
|
-
branches: [main, staging]
|
|
8
|
-
workflow_dispatch:
|
|
9
|
-
|
|
10
|
-
permissions:
|
|
11
|
-
contents: read
|
|
12
|
-
|
|
13
|
-
jobs:
|
|
14
|
-
security:
|
|
15
|
-
name: Security
|
|
16
|
-
uses: ./.github/workflows/security.yml
|
|
17
|
-
with:
|
|
18
|
-
runtime-repository: 0xPlayerOne/code-foundry
|
|
19
|
-
runtime-ref: ${{ github.sha }}
|
|
20
|
-
runner: ubuntu-slim
|
|
21
|
-
secrets: inherit
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
name: Code Foundry
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches: [main, staging]
|
|
6
|
-
pull_request:
|
|
7
|
-
branches: [main, staging]
|
|
8
|
-
workflow_dispatch:
|
|
9
|
-
|
|
10
|
-
permissions:
|
|
11
|
-
contents: read
|
|
12
|
-
|
|
13
|
-
jobs:
|
|
14
|
-
test:
|
|
15
|
-
name: Test
|
|
16
|
-
uses: ./.github/workflows/test.yml
|
|
17
|
-
with:
|
|
18
|
-
runtime-repository: 0xPlayerOne/code-foundry
|
|
19
|
-
runtime-ref: ${{ github.sha }}
|
|
20
|
-
runner: ubuntu-latest
|
|
21
|
-
unit-runner: ubuntu-slim
|
|
22
|
-
secrets: inherit
|