breakaway 2.0.0-main.76 → 2.0.0-main.78
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/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "breakaway",
|
|
3
|
-
"version": "2.0.0-main.
|
|
3
|
+
"version": "2.0.0-main.78",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "breakaway",
|
|
9
|
-
"version": "2.0.0-main.
|
|
9
|
+
"version": "2.0.0-main.78",
|
|
10
10
|
"license": "FSL-1.1-Apache-2.0",
|
|
11
11
|
"bin": {
|
|
12
12
|
"breakaway": "scripts/tasks.mjs"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "breakaway",
|
|
3
|
-
"version": "2.0.0-main.
|
|
3
|
+
"version": "2.0.0-main.78",
|
|
4
4
|
"description": "The task board for you and your coding agents: a Cloudflare Worker, its web app, Taskwarrior sync, and the CLI (npx breakaway).",
|
|
5
5
|
"license": "FSL-1.1-Apache-2.0",
|
|
6
6
|
"type": "module",
|
package/src/infra-cloudflare.js
CHANGED
|
@@ -225,8 +225,8 @@ const MAX_WORKERS = 50;
|
|
|
225
225
|
const MAX_PAGES = 20;
|
|
226
226
|
|
|
227
227
|
/**
|
|
228
|
-
* Paths discover must never call: a KV value, an R2 object,
|
|
229
|
-
* these before it's made, so a bug can't turn a read of settings into a read of data.
|
|
228
|
+
* Paths discover must never call: a KV value, an R2 object, a Worker's code (BRK-188), or its logs (BRK-253). Every
|
|
229
|
+
* call is checked against these before it's made, so a bug can't turn a read of settings into a read of data.
|
|
230
230
|
*/
|
|
231
231
|
export const NEVER_CALLED = [
|
|
232
232
|
/\/storage\/kv\/namespaces\/[^/]+\/(values|keys|bulk)/u,
|
|
@@ -235,6 +235,9 @@ export const NEVER_CALLED = [
|
|
|
235
235
|
/\/workers\/scripts\/[^/]+$/u,
|
|
236
236
|
/\/versions\/[^/?]+\?.*include=modules/u,
|
|
237
237
|
/\/secrets\/[^/]+$/u,
|
|
238
|
+
// Workers Observability's logs and telemetry, and a Worker's live tail: what its requests carried (BRK-253).
|
|
239
|
+
/\/workers\/observability\//u,
|
|
240
|
+
/\/workers\/scripts\/[^/]+\/tails/u,
|
|
238
241
|
];
|
|
239
242
|
|
|
240
243
|
/** A permission as a 403 names it: with its legacy names in parentheses, for a token made before Cloudflare renamed it. */
|
|
@@ -70,7 +70,14 @@ export function checkSwitch(value, field) {
|
|
|
70
70
|
* @param {{ target: string | null }} row
|
|
71
71
|
* @param {string} worker the install's Worker
|
|
72
72
|
*/
|
|
73
|
-
export const runsTheBoard = (row, worker) =>
|
|
73
|
+
export const runsTheBoard = (row, worker) => {
|
|
74
|
+
// Compared as names (BRK-253): ` Breakaway ` is still the install's Worker, so no spelling of it escapes observe only.
|
|
75
|
+
const name = (value) =>
|
|
76
|
+
String(value ?? '')
|
|
77
|
+
.trim()
|
|
78
|
+
.toLowerCase();
|
|
79
|
+
return Boolean(name(row.target)) && name(row.target) === name(worker);
|
|
80
|
+
};
|
|
74
81
|
|
|
75
82
|
/**
|
|
76
83
|
* The environment as the API shows it.
|
package/src/infra-inventory.js
CHANGED
|
@@ -94,3 +94,26 @@ export function resourceView(row, environment, task) {
|
|
|
94
94
|
seen: new Date(row.seen).toISOString(),
|
|
95
95
|
};
|
|
96
96
|
}
|
|
97
|
+
|
|
98
|
+
/** How often the cron refreshes a provider's inventory by itself (BRK-248). */
|
|
99
|
+
export const REFRESH_EVERY_MS = 15 * 60 * 1000;
|
|
100
|
+
|
|
101
|
+
/** At most this many providers refresh on one cron tick, the longest-waiting first, so they stagger. */
|
|
102
|
+
export const REFRESH_PER_TICK = 2;
|
|
103
|
+
|
|
104
|
+
/** A platform's answers that mean the token can't read: the cron stops trying until a new token is pasted. */
|
|
105
|
+
const REFUSED = new Set([401, 403]);
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Whether the cron refreshes a provider now (BRK-248): never refreshed, or not in the last 15 minutes. One whose last
|
|
109
|
+
* refresh the platform refused (401 or 403) waits for a new token instead: Connections already says why.
|
|
110
|
+
* @param {{ at: number, ok: boolean, status: number | null } | null} last the provider's last refresh
|
|
111
|
+
* @param {number} now
|
|
112
|
+
* @param {number | null} [tokenEdited] when the provider's token was last pasted
|
|
113
|
+
*/
|
|
114
|
+
export function refreshDue(last, now, tokenEdited = null) {
|
|
115
|
+
if (!last) return true;
|
|
116
|
+
if (!last.ok && last.status !== null && REFUSED.has(last.status) && !(tokenEdited !== null && tokenEdited > last.at))
|
|
117
|
+
return false;
|
|
118
|
+
return now - last.at >= REFRESH_EVERY_MS;
|
|
119
|
+
}
|
package/template/infra/apply.yml
CHANGED
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
# stops before it reads the write token. That token is CLOUDFLARE_API_TOKEN, a secret of the GitHub environment named
|
|
6
6
|
# for the environment (for every short-lived environment, the one GitHub environment named short-lived), which only
|
|
7
7
|
# {{branchName}} may use. It checks out none of this repository's code: it runs breakaway's runner, pinned to
|
|
8
|
-
# {{version}}
|
|
8
|
+
# {{version}} and installed once, before any step holds the token, from the package's own lockfile with no install
|
|
9
|
+
# scripts, and reports each step to the board. Agents never run this workflow.
|
|
9
10
|
name: Apply infrastructure
|
|
10
11
|
run-name: Apply plan ${{ inputs.plan }} to ${{ inputs.environment }}
|
|
11
12
|
|
|
@@ -47,9 +48,9 @@ jobs:
|
|
|
47
48
|
runs-on: ubuntu-latest
|
|
48
49
|
timeout-minutes: 30
|
|
49
50
|
environment: ${{ inputs.github_environment || inputs.environment }}
|
|
50
|
-
# id-token proves to the board which repository, environment, workflow, and run asks for the plan.
|
|
51
|
+
# id-token proves to the board which repository, environment, workflow, and run asks for the plan. Nothing is
|
|
52
|
+
# checked out, so the run reads nothing of the repository.
|
|
51
53
|
permissions:
|
|
52
|
-
contents: read
|
|
53
54
|
id-token: write
|
|
54
55
|
env:
|
|
55
56
|
BREAKAWAY_URL: ${{ vars.BREAKAWAY_URL }}
|
|
@@ -61,16 +62,22 @@ jobs:
|
|
|
61
62
|
with:
|
|
62
63
|
node-version: 22
|
|
63
64
|
|
|
65
|
+
# The only download: the package ships npm-shrinkwrap.json and has no dependencies, so this installs exactly
|
|
66
|
+
# what was published, and runs none of its scripts. The steps after it run that copy, so nothing is fetched while
|
|
67
|
+
# the write token is in a step's environment.
|
|
68
|
+
- name: Install the runner
|
|
69
|
+
run: npm install --global --ignore-scripts --no-audit --no-fund breakaway@{{version}}
|
|
70
|
+
|
|
64
71
|
- name: Check the plan
|
|
65
|
-
run:
|
|
72
|
+
run: breakaway infra runner check
|
|
66
73
|
|
|
67
74
|
- name: Apply the plan
|
|
68
75
|
env:
|
|
69
76
|
BREAKAWAY_WRITE_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
|
70
|
-
run:
|
|
77
|
+
run: breakaway infra runner apply
|
|
71
78
|
|
|
72
79
|
- name: Report the end
|
|
73
80
|
if: always()
|
|
74
81
|
env:
|
|
75
82
|
OUTCOME: ${{ job.status }}
|
|
76
|
-
run:
|
|
83
|
+
run: breakaway infra runner end
|