@cratis/pi 7.103.2 → 7.103.4
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/package/corpus/harnesses/copilot/instructions/github-actions.instructions.md +26 -5
- package/package/corpus/harnesses/copilot/instructions/go.instructions.md +42 -4
- package/package/corpus/rules/github-actions.md +26 -5
- package/package/corpus/rules/go.md +42 -4
- package/package/corpus/skills/cratis-ci-pipeline-performance/SKILL.md +7 -6
- package/package/corpus/skills/cratis-ci-pipeline-performance/references/caching.md +45 -4
- package/package/corpus/skills/cratis-ci-pipeline-performance/references/required-checks-and-path-filters.md +30 -0
- package/package/corpus/skills/cratis-ci-pipeline-performance/references/runner-sizing-and-images.md +48 -3
- package/package.json +1 -1
|
@@ -19,8 +19,9 @@ paths:
|
|
|
19
19
|
jobs on the Free plan, 5 for macOS). Every queued job competes with every repository.
|
|
20
20
|
- **Public repositories** run free on hosted runners; **private repositories bill every
|
|
21
21
|
minute** — Linux 1×, Windows 2×, macOS 10× — against a small monthly allowance.
|
|
22
|
-
- The organization runs
|
|
23
|
-
do not touch the hosted pool
|
|
22
|
+
- The organization runs self-hosted scale sets on UpCloud (`cratis-arc` and
|
|
23
|
+
`cratis-arc-small`). They do not touch the hosted pool, but share infrastructure
|
|
24
|
+
capacity and cost across Cratis repositories.
|
|
24
25
|
|
|
25
26
|
## Scheduling
|
|
26
27
|
|
|
@@ -54,6 +55,9 @@ paths:
|
|
|
54
55
|
`cancel-in-progress` is false or unset. Keep a single pending slot only for a documented
|
|
55
56
|
design where each run releases everything since the last release, so a replaced run
|
|
56
57
|
loses nothing; say so in a comment beside the `concurrency` block.
|
|
58
|
+
- Avoid duplicate `push` and `pull_request` verification for the same feature-branch
|
|
59
|
+
commit: use pull requests for branch verification and restrict push verification
|
|
60
|
+
to the default branch. Filter unrelated heavy jobs by changed paths.
|
|
57
61
|
- **A required check must not be skippable by `paths:` alone.** A workflow that never
|
|
58
62
|
starts never reports, and the pull request hangs. Gate jobs on a change-detection job
|
|
59
63
|
and require one always-run aggregator job (`if: always()`, checks every `needs.*.result`).
|
|
@@ -74,9 +78,26 @@ paths:
|
|
|
74
78
|
|
|
75
79
|
## Runners
|
|
76
80
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
81
|
+
These are judgment-shaped routing and cache choices. Read the
|
|
82
|
+
[Infrastructure runner guide](https://github.com/Cratis/Infrastructure/blob/main/Documentation/deployment/github-runners.md)
|
|
83
|
+
for UpCloud runner resources, ceilings and storage; link it rather than copying
|
|
84
|
+
capacity numbers into workflows or guidance.
|
|
85
|
+
|
|
86
|
+
- Use GitHub-hosted runners for public repositories (free hosted execution) and jobs
|
|
87
|
+
needing Windows or macOS. Private Linux jobs use `cratis-arc` for builds, specs,
|
|
88
|
+
audits, deployments or Docker; `cratis-arc-small` is only for lightweight script/API
|
|
89
|
+
guards. The small set has no Docker: no container actions, services or Testcontainers.
|
|
90
|
+
A repository runner variable can make routing configurable.
|
|
91
|
+
- Compare job memory and in-job parallelism with the documented limits before
|
|
92
|
+
increasing fan-out. Both sets share nodes; pod ceilings and node cold starts can
|
|
93
|
+
make extra jobs wait. Use the `cratis-ci-pipeline-performance` skill for sizing.
|
|
94
|
+
- Runner pods are ephemeral: workspaces, Docker data and local package downloads do
|
|
95
|
+
not persist between jobs. Use the shared Cratis cache actions, `actions/cache` or
|
|
96
|
+
`setup-*` caching keyed on lockfiles; never assume a warm local package cache.
|
|
97
|
+
- When testing locally packed `0.0.0-ci` packages, a restored global NuGet cache can
|
|
98
|
+
supply stale bytes for the same package ID/version. Use a unique version per run,
|
|
99
|
+
a per-run packages folder, or remove that package from the restored cache before
|
|
100
|
+
restoring consumers. See the skill's `references/caching.md`.
|
|
80
101
|
- On self-hosted runners, `actions/setup-dotnet` cannot write `/usr/share/dotnet`.
|
|
81
102
|
Set `DOTNET_INSTALL_DIR: ${{ runner.temp }}/dotnet` on the setup step.
|
|
82
103
|
- **Never** route `pull_request`-triggered jobs of a *public* repository to self-hosted
|
|
@@ -24,7 +24,9 @@ exact commands.
|
|
|
24
24
|
|
|
25
25
|
- Read the `go` directive, build constraints and CI before choosing a feature.
|
|
26
26
|
The minimum is not the newest locally installed compiler; a `toolchain`
|
|
27
|
-
preference does not replace minimum-version testing. Do not raise it incidentally
|
|
27
|
+
preference does not replace minimum-version testing. Do not raise it incidentally
|
|
28
|
+
or rewrite unrelated code to modernize syntax. Verify unfamiliar APIs against the
|
|
29
|
+
documentation for that minimum, and keep experimental features opt-in.
|
|
28
30
|
- Iterators require Go 1.23; `T.Context` and `B.Loop` require 1.24;
|
|
29
31
|
stable `testing/synctest` and `WaitGroup.Go` require 1.25.
|
|
30
32
|
- Prefer the standard library when it meets the contract. Review dependency
|
|
@@ -33,6 +35,10 @@ exact commands.
|
|
|
33
35
|
including indirect minimum-version changes; keep sums consistent. A consumer
|
|
34
36
|
must not need a developer's workspace or local replacement.
|
|
35
37
|
- Never edit generated code; change its authoritative inputs and pinned generator.
|
|
38
|
+
- Start with a small public package surface aligned with caller workflows; put
|
|
39
|
+
implementation-only packages in `internal/` and keep optional adapters apart from
|
|
40
|
+
core behavior. Do not mandate `pkg/`. Avoid package initialization that performs
|
|
41
|
+
I/O, starts goroutines or mutates globals.
|
|
36
42
|
|
|
37
43
|
## Names, public APIs and values
|
|
38
44
|
|
|
@@ -44,11 +50,23 @@ exact commands.
|
|
|
44
50
|
- Document exported declarations with comments beginning with their names.
|
|
45
51
|
Explain nil/zero semantics, concurrency, ownership, cancellation, error identities
|
|
46
52
|
and cleanup. Add executable examples for important public workflows.
|
|
47
|
-
-
|
|
48
|
-
|
|
53
|
+
- Design exported APIs from realistic caller examples first and export only what
|
|
54
|
+
the library will support. Make zero values useful where possible; reject invalid
|
|
55
|
+
construction early. Use plain parameters or config structs for simple
|
|
56
|
+
configuration and functional options when extensibility outweighs the added
|
|
57
|
+
namespace; document option defaults, validation, ordering and duplicates.
|
|
58
|
+
- Reuse standard interfaces such as `io.Reader` and `http.Handler`; prefer concrete
|
|
59
|
+
returns unless an abstraction is part of the API. Use pointer receivers for
|
|
60
|
+
mutation or values that must not be copied, and avoid public embedding that
|
|
61
|
+
promotes dependency methods. Mark retired API with a `Deprecated:` paragraph
|
|
62
|
+
naming the replacement.
|
|
49
63
|
- Use named domain values instead of interchangeable primitives. Defined types
|
|
50
64
|
do not inherit codec methods; explicitly forward text/JSON codecs and test wire
|
|
51
65
|
formats. See `cratis-fundamentals-concept-go` when using Fundamentals.Go.
|
|
66
|
+
- Specify `Close` ownership, repeated-close behavior and use after close, and
|
|
67
|
+
document concurrent-use guarantees for clients, handles and callbacks.
|
|
68
|
+
- Use generics for meaningful type-safe reuse, not speculative abstraction; do not
|
|
69
|
+
replace domain types with `any` for plumbing convenience.
|
|
52
70
|
- Document whether slices, maps, config and results are owned, copied or borrowed.
|
|
53
71
|
Copying a slice/map header is not a detached copy. Do not copy a used mutex,
|
|
54
72
|
wait group or atomic value, or expose pooled bytes after returning their buffer.
|
|
@@ -62,7 +80,9 @@ exact commands.
|
|
|
62
80
|
return an `error` interface containing a typed nil.
|
|
63
81
|
- Add useful operation context. Handle/log an error at one boundary rather than
|
|
64
82
|
repeatedly logging and returning it. A partial or ambiguous write is not success
|
|
65
|
-
and must not trigger a blind retry.
|
|
83
|
+
and must not trigger a blind retry. Use sentinels for stable categories and typed
|
|
84
|
+
errors for structured details; translate dependency errors whose identity must
|
|
85
|
+
stay internal, and explain intentional suppression.
|
|
66
86
|
- Put `context.Context` first for blocking/cancelable work and propagate it through
|
|
67
87
|
RPCs, HTTP, storage and callbacks. Never escape caller cancellation by replacing
|
|
68
88
|
it with `Background`. Do not retain request contexts in long-lived clients.
|
|
@@ -73,6 +93,9 @@ exact commands.
|
|
|
73
93
|
|
|
74
94
|
## Goroutines, streams and iterators
|
|
75
95
|
|
|
96
|
+
- Prefer synchronous APIs and let callers place concurrency. A saturated
|
|
97
|
+
`errgroup.SetLimit` can block `Go`; use `errgroup` only when its cancellation
|
|
98
|
+
and error behavior fits.
|
|
76
99
|
- Each goroutine needs an owner, termination condition and observable join path.
|
|
77
100
|
Cancellation requests termination; it does not join workers.
|
|
78
101
|
- Bound workers, queues, subscriptions, buffers and retries; define backpressure.
|
|
@@ -85,6 +108,8 @@ exact commands.
|
|
|
85
108
|
- Preserve protocol metadata, tenancy, checkpoints and duplicate-delivery semantics.
|
|
86
109
|
No generic retry or stream helper may promise exactly-once effects.
|
|
87
110
|
- Validate remote TLS identities. Development exceptions must be explicit.
|
|
111
|
+
Bound untrusted payload sizes, fan-out and retained subscription state, and keep
|
|
112
|
+
long-lived subscription lifetimes apart from unary-call deadlines.
|
|
88
113
|
Use cryptographic randomness for secrets, never `math/rand`.
|
|
89
114
|
|
|
90
115
|
## Specifications and checks
|
|
@@ -98,10 +123,23 @@ exact commands.
|
|
|
98
123
|
- Cover error identity, nil/zero input, cancellation/deadlines, partial outcomes,
|
|
99
124
|
early stream exit and resource ownership. Bound fuzz duration and preserve
|
|
100
125
|
failing seeds. Use race checks where supported; race-free does not mean leak-free.
|
|
126
|
+
- Add a regression test for each corrected behavior, including error and boundary
|
|
127
|
+
cases. Use `httptest` or `bufconn` plus real-transport tests where needed, and
|
|
128
|
+
protobuf-aware comparison for generated types.
|
|
129
|
+
- Profile or benchmark a demonstrated problem before optimizing; add no pools,
|
|
130
|
+
caches or `unsafe` without measured justification.
|
|
101
131
|
- Run the repository's build, tests, formatting, vet and pinned golangci-lint gates,
|
|
102
132
|
with race and vulnerability scanning as separate checks. Respect the declared
|
|
103
133
|
minimum without silent toolchain upgrades. Report absent tools honestly.
|
|
104
134
|
|
|
135
|
+
## Compatibility and releases
|
|
136
|
+
|
|
137
|
+
- Prefer additive change: exported signature changes break callers, and adding a
|
|
138
|
+
method to an exported interface breaks its external implementations. Check struct comparability, embedding, defaults, errors and wire shape;
|
|
139
|
+
API-diff tools aid but cannot prove behavioral compatibility.
|
|
140
|
+
- Introduce `/v2` only with a migration and parallel-support plan. Never move a
|
|
141
|
+
published tag; issue a corrective release and retract when needed.
|
|
142
|
+
|
|
105
143
|
## Adaptation and attribution
|
|
106
144
|
|
|
107
145
|
This condensed rule adapts the repository-owned Go baseline at
|
|
@@ -18,8 +18,9 @@ paths:
|
|
|
18
18
|
jobs on the Free plan, 5 for macOS). Every queued job competes with every repository.
|
|
19
19
|
- **Public repositories** run free on hosted runners; **private repositories bill every
|
|
20
20
|
minute** — Linux 1×, Windows 2×, macOS 10× — against a small monthly allowance.
|
|
21
|
-
- The organization runs
|
|
22
|
-
do not touch the hosted pool
|
|
21
|
+
- The organization runs self-hosted scale sets on UpCloud (`cratis-arc` and
|
|
22
|
+
`cratis-arc-small`). They do not touch the hosted pool, but share infrastructure
|
|
23
|
+
capacity and cost across Cratis repositories.
|
|
23
24
|
|
|
24
25
|
## Scheduling
|
|
25
26
|
|
|
@@ -53,6 +54,9 @@ paths:
|
|
|
53
54
|
`cancel-in-progress` is false or unset. Keep a single pending slot only for a documented
|
|
54
55
|
design where each run releases everything since the last release, so a replaced run
|
|
55
56
|
loses nothing; say so in a comment beside the `concurrency` block.
|
|
57
|
+
- Avoid duplicate `push` and `pull_request` verification for the same feature-branch
|
|
58
|
+
commit: use pull requests for branch verification and restrict push verification
|
|
59
|
+
to the default branch. Filter unrelated heavy jobs by changed paths.
|
|
56
60
|
- **A required check must not be skippable by `paths:` alone.** A workflow that never
|
|
57
61
|
starts never reports, and the pull request hangs. Gate jobs on a change-detection job
|
|
58
62
|
and require one always-run aggregator job (`if: always()`, checks every `needs.*.result`).
|
|
@@ -73,9 +77,26 @@ paths:
|
|
|
73
77
|
|
|
74
78
|
## Runners
|
|
75
79
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
80
|
+
These are judgment-shaped routing and cache choices. Read the
|
|
81
|
+
[Infrastructure runner guide](https://github.com/Cratis/Infrastructure/blob/main/Documentation/deployment/github-runners.md)
|
|
82
|
+
for UpCloud runner resources, ceilings and storage; link it rather than copying
|
|
83
|
+
capacity numbers into workflows or guidance.
|
|
84
|
+
|
|
85
|
+
- Use GitHub-hosted runners for public repositories (free hosted execution) and jobs
|
|
86
|
+
needing Windows or macOS. Private Linux jobs use `cratis-arc` for builds, specs,
|
|
87
|
+
audits, deployments or Docker; `cratis-arc-small` is only for lightweight script/API
|
|
88
|
+
guards. The small set has no Docker: no container actions, services or Testcontainers.
|
|
89
|
+
A repository runner variable can make routing configurable.
|
|
90
|
+
- Compare job memory and in-job parallelism with the documented limits before
|
|
91
|
+
increasing fan-out. Both sets share nodes; pod ceilings and node cold starts can
|
|
92
|
+
make extra jobs wait. Use the `cratis-ci-pipeline-performance` skill for sizing.
|
|
93
|
+
- Runner pods are ephemeral: workspaces, Docker data and local package downloads do
|
|
94
|
+
not persist between jobs. Use the shared Cratis cache actions, `actions/cache` or
|
|
95
|
+
`setup-*` caching keyed on lockfiles; never assume a warm local package cache.
|
|
96
|
+
- When testing locally packed `0.0.0-ci` packages, a restored global NuGet cache can
|
|
97
|
+
supply stale bytes for the same package ID/version. Use a unique version per run,
|
|
98
|
+
a per-run packages folder, or remove that package from the restored cache before
|
|
99
|
+
restoring consumers. See the skill's `references/caching.md`.
|
|
79
100
|
- On self-hosted runners, `actions/setup-dotnet` cannot write `/usr/share/dotnet`.
|
|
80
101
|
Set `DOTNET_INSTALL_DIR: ${{ runner.temp }}/dotnet` on the setup step.
|
|
81
102
|
- **Never** route `pull_request`-triggered jobs of a *public* repository to self-hosted
|
|
@@ -23,7 +23,9 @@ exact commands.
|
|
|
23
23
|
|
|
24
24
|
- Read the `go` directive, build constraints and CI before choosing a feature.
|
|
25
25
|
The minimum is not the newest locally installed compiler; a `toolchain`
|
|
26
|
-
preference does not replace minimum-version testing. Do not raise it incidentally
|
|
26
|
+
preference does not replace minimum-version testing. Do not raise it incidentally
|
|
27
|
+
or rewrite unrelated code to modernize syntax. Verify unfamiliar APIs against the
|
|
28
|
+
documentation for that minimum, and keep experimental features opt-in.
|
|
27
29
|
- Iterators require Go 1.23; `T.Context` and `B.Loop` require 1.24;
|
|
28
30
|
stable `testing/synctest` and `WaitGroup.Go` require 1.25.
|
|
29
31
|
- Prefer the standard library when it meets the contract. Review dependency
|
|
@@ -32,6 +34,10 @@ exact commands.
|
|
|
32
34
|
including indirect minimum-version changes; keep sums consistent. A consumer
|
|
33
35
|
must not need a developer's workspace or local replacement.
|
|
34
36
|
- Never edit generated code; change its authoritative inputs and pinned generator.
|
|
37
|
+
- Start with a small public package surface aligned with caller workflows; put
|
|
38
|
+
implementation-only packages in `internal/` and keep optional adapters apart from
|
|
39
|
+
core behavior. Do not mandate `pkg/`. Avoid package initialization that performs
|
|
40
|
+
I/O, starts goroutines or mutates globals.
|
|
35
41
|
|
|
36
42
|
## Names, public APIs and values
|
|
37
43
|
|
|
@@ -43,11 +49,23 @@ exact commands.
|
|
|
43
49
|
- Document exported declarations with comments beginning with their names.
|
|
44
50
|
Explain nil/zero semantics, concurrency, ownership, cancellation, error identities
|
|
45
51
|
and cleanup. Add executable examples for important public workflows.
|
|
46
|
-
-
|
|
47
|
-
|
|
52
|
+
- Design exported APIs from realistic caller examples first and export only what
|
|
53
|
+
the library will support. Make zero values useful where possible; reject invalid
|
|
54
|
+
construction early. Use plain parameters or config structs for simple
|
|
55
|
+
configuration and functional options when extensibility outweighs the added
|
|
56
|
+
namespace; document option defaults, validation, ordering and duplicates.
|
|
57
|
+
- Reuse standard interfaces such as `io.Reader` and `http.Handler`; prefer concrete
|
|
58
|
+
returns unless an abstraction is part of the API. Use pointer receivers for
|
|
59
|
+
mutation or values that must not be copied, and avoid public embedding that
|
|
60
|
+
promotes dependency methods. Mark retired API with a `Deprecated:` paragraph
|
|
61
|
+
naming the replacement.
|
|
48
62
|
- Use named domain values instead of interchangeable primitives. Defined types
|
|
49
63
|
do not inherit codec methods; explicitly forward text/JSON codecs and test wire
|
|
50
64
|
formats. See `cratis-fundamentals-concept-go` when using Fundamentals.Go.
|
|
65
|
+
- Specify `Close` ownership, repeated-close behavior and use after close, and
|
|
66
|
+
document concurrent-use guarantees for clients, handles and callbacks.
|
|
67
|
+
- Use generics for meaningful type-safe reuse, not speculative abstraction; do not
|
|
68
|
+
replace domain types with `any` for plumbing convenience.
|
|
51
69
|
- Document whether slices, maps, config and results are owned, copied or borrowed.
|
|
52
70
|
Copying a slice/map header is not a detached copy. Do not copy a used mutex,
|
|
53
71
|
wait group or atomic value, or expose pooled bytes after returning their buffer.
|
|
@@ -61,7 +79,9 @@ exact commands.
|
|
|
61
79
|
return an `error` interface containing a typed nil.
|
|
62
80
|
- Add useful operation context. Handle/log an error at one boundary rather than
|
|
63
81
|
repeatedly logging and returning it. A partial or ambiguous write is not success
|
|
64
|
-
and must not trigger a blind retry.
|
|
82
|
+
and must not trigger a blind retry. Use sentinels for stable categories and typed
|
|
83
|
+
errors for structured details; translate dependency errors whose identity must
|
|
84
|
+
stay internal, and explain intentional suppression.
|
|
65
85
|
- Put `context.Context` first for blocking/cancelable work and propagate it through
|
|
66
86
|
RPCs, HTTP, storage and callbacks. Never escape caller cancellation by replacing
|
|
67
87
|
it with `Background`. Do not retain request contexts in long-lived clients.
|
|
@@ -72,6 +92,9 @@ exact commands.
|
|
|
72
92
|
|
|
73
93
|
## Goroutines, streams and iterators
|
|
74
94
|
|
|
95
|
+
- Prefer synchronous APIs and let callers place concurrency. A saturated
|
|
96
|
+
`errgroup.SetLimit` can block `Go`; use `errgroup` only when its cancellation
|
|
97
|
+
and error behavior fits.
|
|
75
98
|
- Each goroutine needs an owner, termination condition and observable join path.
|
|
76
99
|
Cancellation requests termination; it does not join workers.
|
|
77
100
|
- Bound workers, queues, subscriptions, buffers and retries; define backpressure.
|
|
@@ -84,6 +107,8 @@ exact commands.
|
|
|
84
107
|
- Preserve protocol metadata, tenancy, checkpoints and duplicate-delivery semantics.
|
|
85
108
|
No generic retry or stream helper may promise exactly-once effects.
|
|
86
109
|
- Validate remote TLS identities. Development exceptions must be explicit.
|
|
110
|
+
Bound untrusted payload sizes, fan-out and retained subscription state, and keep
|
|
111
|
+
long-lived subscription lifetimes apart from unary-call deadlines.
|
|
87
112
|
Use cryptographic randomness for secrets, never `math/rand`.
|
|
88
113
|
|
|
89
114
|
## Specifications and checks
|
|
@@ -97,10 +122,23 @@ exact commands.
|
|
|
97
122
|
- Cover error identity, nil/zero input, cancellation/deadlines, partial outcomes,
|
|
98
123
|
early stream exit and resource ownership. Bound fuzz duration and preserve
|
|
99
124
|
failing seeds. Use race checks where supported; race-free does not mean leak-free.
|
|
125
|
+
- Add a regression test for each corrected behavior, including error and boundary
|
|
126
|
+
cases. Use `httptest` or `bufconn` plus real-transport tests where needed, and
|
|
127
|
+
protobuf-aware comparison for generated types.
|
|
128
|
+
- Profile or benchmark a demonstrated problem before optimizing; add no pools,
|
|
129
|
+
caches or `unsafe` without measured justification.
|
|
100
130
|
- Run the repository's build, tests, formatting, vet and pinned golangci-lint gates,
|
|
101
131
|
with race and vulnerability scanning as separate checks. Respect the declared
|
|
102
132
|
minimum without silent toolchain upgrades. Report absent tools honestly.
|
|
103
133
|
|
|
134
|
+
## Compatibility and releases
|
|
135
|
+
|
|
136
|
+
- Prefer additive change: exported signature changes break callers, and adding a
|
|
137
|
+
method to an exported interface breaks its external implementations. Check struct comparability, embedding, defaults, errors and wire shape;
|
|
138
|
+
API-diff tools aid but cannot prove behavioral compatibility.
|
|
139
|
+
- Introduce `/v2` only with a migration and parallel-support plan. Never move a
|
|
140
|
+
published tag; issue a corrective release and retract when needed.
|
|
141
|
+
|
|
104
142
|
## Adaptation and attribution
|
|
105
143
|
|
|
106
144
|
This condensed rule adapts the repository-owned Go baseline at
|
|
@@ -111,11 +111,12 @@ when keyed on `github.ref` for merged `pull_request` `closed` events). A workflo
|
|
|
111
111
|
whose release tooling aggregates since the last release may keep one pending slot,
|
|
112
112
|
documented. Read `references/publish-pipelines.md`.
|
|
113
113
|
|
|
114
|
-
**Runner routing.** Fits queue-bound workflows.
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
114
|
+
**Runner routing.** Fits queue-bound workflows. Read the
|
|
115
|
+
[Infrastructure runner guide](https://github.com/Cratis/Infrastructure/blob/main/Documentation/deployment/github-runners.md)
|
|
116
|
+
for the UpCloud scale sets `cratis-arc` and `cratis-arc-small`; do not copy its
|
|
117
|
+
capacity numbers. The rule owns routing and public-fork safety. Read
|
|
118
|
+
`references/runner-sizing-and-images.md` when choosing hosted versus self-hosted
|
|
119
|
+
runners, sizing in-job parallelism or weighing fan-out against cold starts.
|
|
119
120
|
|
|
120
121
|
**Publish from tested artifacts.** Fits release workflows that rebuild what the
|
|
121
122
|
pull-request run already built and tested. Default: build and pack once, then
|
|
@@ -195,7 +196,7 @@ touches `permissions:`, uses `pull_request_target`, or adds a cache.
|
|
|
195
196
|
- Read `references/publish-pipelines.md` when a release or deploy workflow queues, drops runs or rebuilds.
|
|
196
197
|
- Read `references/flaky-and-hung-jobs.md` when runs fail, hang or are rerun.
|
|
197
198
|
- Read `references/test-setup-cost.md` when test steps outlast reported test time, tests duplicate a dependency's suite, or compiles repeat per push.
|
|
198
|
-
- Read `references/runner-sizing-and-images.md` when jobs are uniformly slow, pull images, install tools or reuse workspaces.
|
|
199
|
+
- Read `references/runner-sizing-and-images.md` when choosing runners, sizing parallelism, or when jobs are uniformly slow, pull images, install tools or reuse workspaces.
|
|
199
200
|
- Read `references/security-and-pinning.md` when a change touches actions, permissions, triggers or caches.
|
|
200
201
|
- Read `references/sources.md` when attributing or extending the method.
|
|
201
202
|
- Execute `scripts/ci-timings.sh` for every measurement; read it only to change it. Its self-test reads the synthetic inputs `scripts/fixtures/runs.json` and `scripts/fixtures/jobs/1003.json`, `scripts/fixtures/jobs/1007.json`, `scripts/fixtures/jobs/1010.json`; edit them only together with the expected lines in the script.
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
# Caching
|
|
2
2
|
|
|
3
|
-
Use this when a job spends measurable time restoring packages, installing a
|
|
4
|
-
frontend toolchain or rebuilding Docker layers. Check the slowest-steps table
|
|
5
|
-
first: a step under a minute is not worth a cache.
|
|
6
|
-
|
|
7
3
|
## Contents
|
|
8
4
|
|
|
9
5
|
- Shared Cratis cache actions
|
|
6
|
+
- Ephemeral runner pods
|
|
10
7
|
- NuGet and Yarn determinism
|
|
8
|
+
- Locally packed CI packages
|
|
11
9
|
- Docker layer cache
|
|
12
10
|
- Scope, eviction and safety
|
|
13
11
|
|
|
12
|
+
Use this when a job spends measurable time restoring packages, installing a
|
|
13
|
+
frontend toolchain or rebuilding Docker layers. Check the slowest-steps table
|
|
14
|
+
first: a step under a minute is not worth a cache.
|
|
15
|
+
|
|
14
16
|
## Shared Cratis cache actions
|
|
15
17
|
|
|
16
18
|
The `Cratis/Workflows` repository ships two composite actions. Use them instead
|
|
@@ -35,6 +37,17 @@ key and one path list.
|
|
|
35
37
|
workflow on that branch never warms one. Add a scheduled warm-up workflow that
|
|
36
38
|
runs the same restore and build.
|
|
37
39
|
|
|
40
|
+
## Ephemeral runner pods
|
|
41
|
+
|
|
42
|
+
Cratis self-hosted runners use per-job pods: workspace files, package downloads
|
|
43
|
+
and Docker data disappear with the job. A warm runner or node image does not make
|
|
44
|
+
`~/.nuget/packages`, the Yarn/npm download cache or BuildKit layers persistent.
|
|
45
|
+
Use the shared actions above, or explicit `actions/cache` / `setup-*` dependency
|
|
46
|
+
caching when the shared actions do not fit. Key downloads on the OS, toolchain and
|
|
47
|
+
committed lockfiles (`packages.lock.json`, `yarn.lock` or `package-lock.json`),
|
|
48
|
+
and use remote Docker layer caching below. Do not cache `node_modules` as a
|
|
49
|
+
substitute for an immutable install.
|
|
50
|
+
|
|
38
51
|
## NuGet and Yarn determinism
|
|
39
52
|
|
|
40
53
|
A cache is only as stable as its key. Make the key inputs deterministic.
|
|
@@ -48,6 +61,34 @@ A cache is only as stable as its key. Make the key inputs deterministic.
|
|
|
48
61
|
caches across commits are rarely correct; share build output within a run as an
|
|
49
62
|
artifact instead (see `build-once-and-shard.md`).
|
|
50
63
|
|
|
64
|
+
## Locally packed CI packages
|
|
65
|
+
|
|
66
|
+
A repository that packs `0.0.0-ci` repeatedly and tests a consumer can restore an
|
|
67
|
+
older package with the same ID/version from cached `~/.nuget/packages`. NuGet can
|
|
68
|
+
reuse the extracted package without reading the newly packed bytes, so a green
|
|
69
|
+
consumer test may exercise the wrong code. A lockfile cache key alone does not
|
|
70
|
+
fix an unchanged local package version.
|
|
71
|
+
|
|
72
|
+
Default: pack a unique prerelease version per run and attempt, and make the
|
|
73
|
+
consumer reference that exact version. If the version must stay fixed, set a
|
|
74
|
+
per-run packages folder for **every restore/build/test that can restore** in both
|
|
75
|
+
the producer and consumer, and do not restore the global package cache into it:
|
|
76
|
+
|
|
77
|
+
```yaml
|
|
78
|
+
env:
|
|
79
|
+
NUGET_PACKAGES: ${{ runner.temp }}/nuget-${{ github.run_id }}-${{ github.run_attempt }}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Alternatively, after cache restoration and before consumer restore, remove only
|
|
83
|
+
the locally packed package's ID/version directory from the global packages
|
|
84
|
+
folder. Keep unrelated dependency downloads cached. A fresh runner is not enough
|
|
85
|
+
if the workflow restores stale package bytes from a remote cache.
|
|
86
|
+
|
|
87
|
+
Verify with `dotnet restore <consumer.csproj> --verbosity normal` followed by the
|
|
88
|
+
consumer's focused test command. Pass means restore resolves the newly packed
|
|
89
|
+
ID/version from the intended feed/folder and the test exercises behavior added
|
|
90
|
+
in that package, not merely that a cached restore succeeds.
|
|
91
|
+
|
|
51
92
|
## Docker layer cache
|
|
52
93
|
|
|
53
94
|
```yaml
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
- The hang
|
|
6
6
|
- Change detection and the aggregator
|
|
7
|
+
- Avoiding redundant runs
|
|
7
8
|
- Keeping required checks stable
|
|
8
9
|
- Merge queue
|
|
9
10
|
|
|
@@ -82,6 +83,35 @@ jobs:
|
|
|
82
83
|
build). For one event, `paths` and `paths-ignore` cannot be combined; use
|
|
83
84
|
`paths` with `!` negation patterns.
|
|
84
85
|
|
|
86
|
+
## Avoiding redundant runs
|
|
87
|
+
|
|
88
|
+
On the shared Cratis runner pools, two events for the same feature-branch commit
|
|
89
|
+
consume capacity that another repository needs. Verify open pull requests through
|
|
90
|
+
`pull_request` and restrict push verification to the default branch:
|
|
91
|
+
|
|
92
|
+
```yaml
|
|
93
|
+
on:
|
|
94
|
+
pull_request:
|
|
95
|
+
push:
|
|
96
|
+
branches: [main]
|
|
97
|
+
concurrency:
|
|
98
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
99
|
+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Use the repository's actual default branch. Keep publish/release/deploy workflows
|
|
103
|
+
separate and follow their non-cancelling queue rules in
|
|
104
|
+
[github-actions.md](../../../rules/github-actions.md). Cancellation stops obsolete
|
|
105
|
+
PR runs; it does not deduplicate `push` and `pull_request` events, whose refs differ.
|
|
106
|
+
Use change detection above to avoid unrelated heavy jobs without suppressing the
|
|
107
|
+
required aggregator. Retain any required `merge_group` trigger as described below.
|
|
108
|
+
|
|
109
|
+
Verify event deduplication with
|
|
110
|
+
`gh run list --workflow <workflow.yml> --commit <sha> --json event,headSha,status`:
|
|
111
|
+
a PR update should have one verification run for that workflow, not both a push
|
|
112
|
+
and a pull-request run. Check that a superseded PR run cancels, unrelated paths
|
|
113
|
+
skip heavy jobs, and the required aggregator still reports.
|
|
114
|
+
|
|
85
115
|
## Keeping required checks stable
|
|
86
116
|
|
|
87
117
|
Branch protection matches check names. Renaming a job, changing a matrix key or
|
package/package/corpus/skills/cratis-ci-pipeline-performance/references/runner-sizing-and-images.md
CHANGED
|
@@ -1,16 +1,55 @@
|
|
|
1
1
|
# Runner sizing, images and cache layers
|
|
2
2
|
|
|
3
|
-
Use this when every job is uniformly slow, when jobs spend time pulling or
|
|
4
|
-
installing tools, or when deciding how to warm workspaces.
|
|
5
|
-
|
|
6
3
|
## Contents
|
|
7
4
|
|
|
5
|
+
- Choosing Cratis runners
|
|
8
6
|
- Cores per job before job count
|
|
9
7
|
- Container images
|
|
10
8
|
- Tools baked into the runner image
|
|
11
9
|
- Cache layers and warm workspaces
|
|
12
10
|
- Publish stages
|
|
13
11
|
|
|
12
|
+
Use this when every job is uniformly slow, when jobs spend time pulling or
|
|
13
|
+
installing tools, or when choosing runners and deciding how to warm workspaces.
|
|
14
|
+
|
|
15
|
+
## Choosing Cratis runners
|
|
16
|
+
|
|
17
|
+
Read the [Infrastructure runner guide](https://github.com/Cratis/Infrastructure/blob/main/Documentation/deployment/github-runners.md)
|
|
18
|
+
for the UpCloud scale sets, resource requests and limits, pod ceilings, scratch
|
|
19
|
+
storage and autoscaling. Keep those numbers there, not in this skill. The routing
|
|
20
|
+
and public-fork safety invariants live in
|
|
21
|
+
[github-actions.md](../../../rules/github-actions.md).
|
|
22
|
+
|
|
23
|
+
Choose by the work, not just the queue length:
|
|
24
|
+
|
|
25
|
+
| Choice | When it fits | Check before routing |
|
|
26
|
+
|---|---|---|
|
|
27
|
+
| GitHub-hosted | Public repositories, Windows/macOS jobs | Public hosted execution is free; compare queue and startup time, not just billed minutes |
|
|
28
|
+
| `cratis-arc-small` | Lightweight script/API guards such as release-note or work-record checks | No Docker daemon, container actions, service containers or Testcontainers; not for builds, specs, audits or deployments |
|
|
29
|
+
| `cratis-arc` | Private Linux builds, specs, dependency audits, deployments and Docker work | Fit peak memory, worker count and scratch use inside the documented limits |
|
|
30
|
+
|
|
31
|
+
For example, a private-repository release-note script can use
|
|
32
|
+
`runs-on: cratis-arc-small`; a private-repository Testcontainers suite needs
|
|
33
|
+
`runs-on: cratis-arc`.
|
|
34
|
+
|
|
35
|
+
- Measure peak memory for the whole job, including Docker services and test
|
|
36
|
+
workers. Leave headroom below the documented limit; an OOM is not evidence that
|
|
37
|
+
more shards will help when those shards share nodes.
|
|
38
|
+
- Set build/test worker counts from the pod's CPU and memory limits, not the
|
|
39
|
+
node's advertised cores. A larger in-job worker count can cause contention.
|
|
40
|
+
- Compare fan-out with each set's pod ceiling and the shared node pool. More
|
|
41
|
+
shards can wait for slots or node autoscaling instead of shortening the run.
|
|
42
|
+
- Include runner startup, image pulls and fresh-node provisioning in wall time.
|
|
43
|
+
For short jobs, merge compatible checks with one setup before adding shards;
|
|
44
|
+
compare the hosted alternative where routing policy permits it.
|
|
45
|
+
- Reduce redundant work before requesting capacity: apply PR cancellation,
|
|
46
|
+
change-detected heavy jobs and event deduplication as described in
|
|
47
|
+
`required-checks-and-path-filters.md` and the owning rule.
|
|
48
|
+
|
|
49
|
+
Do not infer live node counts, runner cost/quotas, network/egress policy or shared
|
|
50
|
+
package-cache availability from the YAML. Record missing operational facts in
|
|
51
|
+
Infrastructure, not as assumptions in the corpus.
|
|
52
|
+
|
|
14
53
|
## Cores per job before job count
|
|
15
54
|
|
|
16
55
|
Undersized runner pods (a small CPU request or limit) make every job slow, and more
|
|
@@ -45,6 +84,12 @@ a version check. Keep the image's contents versioned so a change is reviewable.
|
|
|
45
84
|
Prefer content-addressed caches, which are correct by construction, before
|
|
46
85
|
warm volumes:
|
|
47
86
|
|
|
87
|
+
Cratis runner pods start with per-job workspaces and Docker storage; neither is
|
|
88
|
+
a persistent shared NuGet, npm or BuildKit cache. Restore remote caches explicitly
|
|
89
|
+
(see `caching.md`) rather than treating a previous job's downloads as available.
|
|
90
|
+
The layers below are options to configure, not claims that Infrastructure provides
|
|
91
|
+
them:
|
|
92
|
+
|
|
48
93
|
1. A registry mirror or pull-through cache for images.
|
|
49
94
|
2. A remote or registry-backed BuildKit cache (see `caching.md`).
|
|
50
95
|
3. Package caches keyed by lock files.
|