DashboardcraftSession 03PFlPby6D69

Session 03PFlPby6D69

Full ID: 03PFlPby6D694Ua6q
Messages: 33
Distillations: 13
Time range: 2026-09-03 15:50:43 — 2026-09-03 17:00:52

Conversation (33 messages)

Work only in /home/byk/Code/getsentry/publish-workspace-acceptance. Implement the user-approved replacement of unpublished JSON workspace titles with path-based full-suffix workspace resolution. Do not touch Craft. Existing unpublished [workspace: JSON] grammar and workspace parsed field must be removed. Workspace meanings must be resolved after exact CI revision checkout by matching the complete non-root title suffix against exact concrete discovered workspace paths (including paths expanded from globs), before falling back to checkout path. Update parser grammar/generated parser via existing generator, details parser, location resolver/script, workflow's location resolution, tests, and docs as required. Also address known review suggestions where naturally related: actions/checkout@v7 in ci-poller, move inline JS from publish workflow to runnable Node scripts, single source for grammar/docs if feasible, assess/request-header parser integration. Preserve current unrelated whitespace changes in src/modules/post-workflow-details.js and src/publish/inputs.js. Use Yarn only for Publish package tooling. Run focused tests and report exact changed files, verification results, remaining decisions/blockers. Do not commit/push or modify review threads.

gateway · 2026-09-03 15:50:43
result
<path>/home/byk/Code/getsentry/publish-workspace-acceptance</path>
<type>directory</type>
<entries>
.eslintrc.js
.git
.github/
.gitignore
AGENTS.md
auto-approve-repos.txt
docs/
LICENSE
node_modules/
package.json
README.md
scripts/
src/
vitest.config.js
yarn.lock

(15 entries)
</entries>
gateway · 2026-09-03 15:52:17

I’ll map the existing title, checkout, and location-resolution flow first, then replace it while preserving the two unrelated whitespace-only files.

gpt-5.6-terra · 2026-09-03 15:52:17 · ~27 tokens
result
## feat/workspace-acceptance...origin/feat/workspace-acceptance
 M src/modules/post-workflow-details.js
 M src/publish/inputs.js
52ef600 feat: resolve compact workspace publish requests
b658ffa fix: validate publish workspace JSON
33de3f1 feat: accept workspace publish requests
83d210b build(deps): bump js-yaml from 4.3.0 to 4.3.1 (#9174)
5268a23 feat: Add Vercel creds
/home/byk/Code/getsentry/publish-workspace-acceptance
gateway · 2026-09-03 15:54:39
result
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/AGENTS.md</path>
<type>file</type>
<content>
1: # AGENTS.md - Coding Agent Guidelines
2: 
3: This document provides guidelines for AI coding agents working in this repository.
4: 
5: ## Project Overview
6: 
7: This is the **Sentry Publish Repository** - a GitHub Actions-based approval system for publishing releases across multiple Sentry projects using [Craft](https://github.com/getsentry/craft). It's a pure JavaScript (Node.js 24.0.0) project using CommonJS modules.
8: 
9: ## Build/Lint/Test Commands
10: 
11: ### Package Manager
12: 
13: - **Yarn 1.22.22** (classic) - Do NOT use npm
14: - Version management via Volta (pinned in package.json)
15: 
16: ### Commands
17: 
18: ```bash
19: # Install dependencies
20: yarn install
21: 
22: # Run all tests
23: yarn test
24: 
25: # Run tests in watch mode
26: yarn test:watch
27: 
28: # Run a single test file
29: yarn test src/modules/__tests__/update-issue.js
30: 
31: # Run tests ...
gateway · 2026-09-03 15:57:04
result
/home/byk/Code/getsentry/publish-workspace-acceptance/scripts/generate-publish-issue-title-parser.js
/home/byk/Code/getsentry/publish-workspace-acceptance/package.json
/home/byk/Code/getsentry/publish-workspace-acceptance/LICENSE
/home/byk/Code/getsentry/publish-workspace-acceptance/AGENTS.md
/home/byk/Code/getsentry/publish-workspace-acceptance/.gitignore
/home/byk/Code/getsentry/publish-workspace-acceptance/.github/workflows/test.yml
/home/byk/Code/getsentry/publish-workspace-acceptance/.github/workflows/publish.yml
/home/byk/Code/getsentry/publish-workspace-acceptance/.github/workflows/cocoapods-keepalive.yml
/home/byk/Code/getsentry/publish-workspace-acceptance/.github/workflows/ci-poller.yml
/home/byk/Code/getsentry/publish-workspace-acceptance/.github/workflows/auto-approve.yml
/home/byk/Code/getsentry/publish-workspace-acceptance/.github/CODEOWNERS
/home/byk/Code/getsentry/publish-workspace-acceptance/.eslintrc.js
/home/byk/Code/getsentry/publish-workspace-acceptance/.git
/home/...
gateway · 2026-09-03 15:58:25
result
Found 100 matches (more matches available)
/home/byk/Code/getsentry/publish-workspace-acceptance/scripts/generate-publish-issue-title-parser.js:
  Line 11:   "publish-issue-title.peggy"

  Line 18:   "publish-issue-title.js"

  Line 23:   grammarSource: "publish-issue-title.peggy",


/home/byk/Code/getsentry/publish-workspace-acceptance/package.json:
  Line 18:     "generate": "node scripts/generate-publish-issue-title-parser.js",

  Line 19:     "check:generated": "node scripts/generate-publish-issue-title-parser.js --check",


/home/byk/Code/getsentry/publish-workspace-acceptance/.github/workflows/test.yml:
  Line 19:       - uses: actions/checkout@v6


/home/byk/Code/getsentry/publish-workspace-acceptance/.github/workflows/publish.yml:
  Line 120:         uses: actions/checkout@v6

  Line 159:       - uses: actions/checkout@v6

  Line 169:       - name: Resolve publish location

  Line 170:         id: location

  Line 174:           workspace_names='[]'

  Line 175:           ...
gateway · 2026-09-03 16:00:55
result
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/src/modules/publish-issue-title.peggy</path>
<type>file</type>
<content>
1: {
2:   function join(characters) {
3:     return characters.join("");
4:   }
5: }
6: 
7: // Canonical grammar for publish issue titles. A path suffix is syntactic only:
8: // the controller resolves a single segment as a workspace after checking out
9: // the CI-approved revision.
10: PublishIssueTitle
11:   = "publish: " "getsentry/"? repo:Repository path:Path? workspace:LegacyWorkspace? "@" version:Version !. {
12:       return {
13:         repo,
14:         path: path || "",
15:         version,
16:         ...(workspace ? { workspace } : {}),
17:       };
18:     }
19: 
20: Repository
21:   = characters:RepositoryCharacter+ { return join(characters); }
22: 
23: RepositoryCharacter
24:   = [A-Za-z0-9_.-]
25: 
26: Path
27:   = segments:("/" segment:PathSegment { return `/${segment}`; })+ { return join(segments); }
28: 
29: PathSegment
30:   = ...
gateway · 2026-09-03 16:03:24
result
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/src/modules/details-from-context.js</path>
<type>file</type>
<content>
1: const { parse: parsePublishIssueTitle } = require("./publish-issue-title");
2: 
3: /**
4:  * Matches the entire "Targets" section of a github publish issue body.
5:  */
6: const TARGETS_SECTION_PARSER_REGEX =
7:   /^(?!### Targets$\s)(?: *- \[[ xX]\] \S+\s*$(?:\r?\n)?)+/m;
8: 
9: /**
10:  * Matches all targets of a github publish issue body in a section that was already matched and extracted with `TARGETS_PARSER_REGEX`.
11:  * The "id" of the targets is captured within a capture group.
12:  */
13: const TARGETS_PARSER_REGEX = /^\s*- \[[ x]\] (\S+)/gim;
14: 
15: /**
16:  * Matches checked targets of a github publish issue body in a section that was already matched and extracted with `TARGETS_PARSER_REGEX`.
17:  * The "id" of the targets is captured within a capture group. ...
gateway · 2026-09-03 16:03:28
result
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/src/modules/publish-location.js</path>
<type>file</type>
<content>
1: function needsWorkspaceDiscovery({ path, workspace }) {
2:   return !workspace && /^\.\/[A-Za-z0-9_.-]+$/.test(path);
3: }
4: 
5: function resolvePublishLocation({ path, workspace, workspaceNames }) {
6:   if (workspace) {
7:     if (path !== ".") {
8:       throw new Error("A publish workspace must use the repository root path.");
9:     }
10:     return { path, workspace };
11:   }
12: 
13:   if (!needsWorkspaceDiscovery({ path, workspace })) {
14:     return { path };
15:   }
16: 
17:   if (!workspaceNames.every(isWorkspaceName)) {
18:     throw new Error(
19:       "Craft workspace discovery returned an invalid workspace list."
20:     );
21:   }
22: 
23:   const segments = path.slice(2).split("/");
24:   if (
25:     path.startsWith("./") &&
26:     segments.length === 1 &&
27:     workspaceNames.includes(segments[0])
28:   ) {
29:     return { path: ...
gateway · 2026-09-03 16:03:31
result
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/src/publish/resolve-location.js</path>
<type>file</type>
<content>
1: const core = require("@actions/core");
2: const {
3:   needsWorkspaceDiscovery,
4:   resolvePublishLocation,
5: } = require("../modules/publish-location");
6: 
7: function resolveLocation() {
8:   const input = JSON.parse(process.env.PUBLISH_ARGS || "");
9:   const workspaceNames = needsWorkspaceDiscovery(input)
10:     ? JSON.parse(process.env.CRAFT_WORKSPACE_NAMES || "")
11:     : [];
12: 
13:   if (!Array.isArray(workspaceNames)) {
14:     throw new Error(
15:       "Craft workspace discovery returned an invalid workspace list."
16:     );
17:   }
18: 
19:   core.setOutput(
20:     "result",
21:     resolvePublishLocation({
22:       path: input.path,
23:       workspace: input.workspace,
24:       workspaceNames,
25:     })
26:   );
27: }
28: 
29: resolveLocation();

(End of file - total 29 lines)
</content>
gateway · 2026-09-03 16:04:38
result
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/.github/workflows/publish.yml</path>
<type>file</type>
<content>
1: name: Publish
2: on:
3:   issues:
4:     types: [labeled]
5: 
6: concurrency:
7:   # Use the issue title (e.g. "publish: getsentry/foo@1.2.3") so duplicate
8:   # issues for the same repo@version share a concurrency group.
9:   group: ${{ github.event.issue.title }}
10:   cancel-in-progress: false
11: 
12: permissions:
13:   contents: read
14:   issues: write
15:   packages: write
16: 
17: jobs:
18:   # When accepted is added to a publish issue:
19:   #   - Add ci-pending (and remove ci-failed if retrying)
20:   #   - Enable the poller via CI_POLLER_HAS_PENDING=true
21:   #   - Comment on the issue
22:   #   - Trigger the poller immediately so we don't wait for the next cron tick
23:   # The publish job below requires ci-ready, so it will not fire until the
24:   # poller flips ci-pending → ci-ready (which also prevents publishing without
25:   # CI ...
gateway · 2026-09-03 16:08:06
result
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/src/modules/__tests__/details-from-context.js</path>
<type>file</type>
<content>
1: import { test, expect } from "vitest";
2: 
3: const { detailsFromContext } = require("../details-from-context.js");
4: 
5: const inputsArgs = {
6:   context: {
7:     repo: { owner: "getsentry", repo: "publish" },
8:     payload: {
9:       issue: {
10:         number: "223",
11:         title: "publish: getsentry/sentry@21.3.1",
12:         body: `
13: Requested by: @BYK
14: 
15: Merge target: custom-branch
16: 
17: Quick links:
18: - [View changes](https://github.com/getsentry/sentry/compare/21.3.0...refs/heads/releases/21.3.1)
19: - [View check runs](https://github.com/getsentry/sentry/commit/7e5ca7ed5581552de066e2a8bc295b8306be38ac/checks/)
20: 
21: Assign the **accepted** label to this issue to approve the release. ...
gateway · 2026-09-03 16:08:14
result
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/src/modules/__tests__/details-from-context.js</path>
<type>file</type>
<content>
300:           issue: {
301:             title:
302:               'publish: getsentry/toolkit [workspace: "cli\\u2029next"] @1.2.3',
303:             body: "",
304:             labels: [],
305:           },
306:         },
307:       },
308:     });
309: 
310:   await expect(emptyWorkspace).rejects.toThrow(
311:     "Workspace names must be nonempty and cannot contain Unicode control, format, or separator characters"
312:   );
313:   await expect(multilineWorkspace).rejects.toThrow(
314:     "Workspace names must be nonempty and cannot contain Unicode control, format, or separator characters"
315:   );
316:   await expect(nulWorkspace).rejects.toThrow(
317:     "Workspace names must be nonempty and cannot contain Unicode control, format, or separator characters"
318:   );
319:   await expect(tabWorkspace).rejects.toThrow(
320:     "Workspace ...
gateway · 2026-09-03 16:10:39
result
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/src/modules/__tests__/publish-location.js</path>
<type>file</type>
<content>
1: import { expect, test } from "vitest";
2: 
3: const {
4:   needsWorkspaceDiscovery,
5:   resolvePublishLocation,
6: } = require("../publish-location.js");
7: 
8: test.each([
9:   [{ path: "./cli" }, true],
10:   [{ path: "./packages/cli" }, false],
11:   [{ path: "." }, false],
12:   [{ path: "./cli", workspace: "cli" }, false],
13: ])("workspace discovery is %s for %j", (input, expected) => {
14:   expect(needsWorkspaceDiscovery(input)).toBe(expected);
15: });
16: 
17: test("classifies an exact one-segment workspace without normalizing it", () => {
18:   expect(
19:     resolvePublishLocation({
20:       path: "./CLI",
21:       workspaceNames: ["cli", "CLI"],
22:     })
23:   ).toStrictEqual({ path: ".", workspace: "CLI" });
24: });
25: 
26: test("keeps a non-workspace suffix as a checkout path", () => {
27:   expect(
28:     ...
gateway · 2026-09-03 16:10:50
result
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/scripts/generate-publish-issue-title-parser.js</path>
<type>file</type>
<content>
1: const fs = require("fs");
2: const path = require("path");
3: const peggy = require("peggy");
4: const prettier = require("prettier");
5: 
6: const grammarPath = path.join(
7:   __dirname,
8:   "..",
9:   "src",
10:   "modules",
11:   "publish-issue-title.peggy"
12: );
13: const outputPath = path.join(
14:   __dirname,
15:   "..",
16:   "src",
17:   "modules",
18:   "publish-issue-title.js"
19: );
20: const grammar = fs.readFileSync(grammarPath, "utf8");
21: const parser = peggy.generate(grammar, {
22:   format: "commonjs",
23:   grammarSource: "publish-issue-title.peggy",
24:   output: "source",
25: });
26: 
27: const generatedParser = prettier.format(`/* eslint-disable */\n${parser}`, {
28:   filepath: outputPath,
29: });
30: 
31: if (process.argv.includes("--check")) {
32:   const currentParser = fs.readFileSync(outputPath, "utf8");
33:   ...
gateway · 2026-09-03 16:10:54
result
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/docs/publish-issue-format.md</path>
<type>file</type>
<content>
1: # Publish Issue Format
2: 
3: The Publish workflow treats a publish issue as a release request. The title identifies
4: the release; the body supplies the merge target and selected targets. Do not edit the
5: title by hand unless it remains valid under this format.
6: 
7: ## Title
8: 
9: Every title starts with `publish: `. This EBNF is canonical:
10: 
11: ```text
12: title             = "publish: ", [ "getsentry/" ], repository, [ path ],
13:                     [ legacy-workspace ], "@", version ;
14: repository        = token, { token } ;
15: path              = "/", path-segment, { "/", path-segment } ;
16: path-segment      = token, { token } ;
17: legacy-workspace  = " [workspace: ", json-string, "] " ;
18: version           = version-character, { version-character } ;
19: token             = ? ASCII letter, digit, ".", "_", or "-" ? ...
gateway · 2026-09-03 16:13:28
result
Found 1 matches
/home/byk/Code/getsentry/publish-workspace-acceptance/README.md:
  Line 49: To enable calendar versioning, add the following to your `.craft.yml`:
gateway · 2026-09-03 16:13:36
result
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/src/publish/inputs.js</path>
<type>file</type>
<content>
1: const github = require('@actions/github');
2: const core = require('@actions/core');
3: const { detailsFromContext } = require('../modules/details-from-context');
4: 
5: async function inputs() {
6:     const result = await detailsFromContext({
7:       context: github.context,
8:     });
9:     core.setOutput('result', result);
10: }
11: 
12: inputs();

(End of file - total 12 lines)
</content>
gateway · 2026-09-03 16:17:11
result
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/src/modules/post-workflow-details.js</path>
<type>file</type>
<content>
1: async function postWorkflowDetails({context, octokit}) {
2:   const { repo: publishRepo, runId: run_id } = context;
3:   const { number: issue_number } = context.payload.issue;
4: 
5:   const workflowInfo = (
6:     await octokit.rest.actions.getWorkflowRun({
7:       ...publishRepo,
8:       run_id,
9:     })
10:   ).data;
11: 
12:   return octokit.rest.issues.createComment({
13:     ...publishRepo,
14:     issue_number,
15:     body: `Publishing: [run#${run_id}](${workflowInfo.html_url})`,
16:   });
17: }
18: 
19: module.exports = postWorkflowDetails;

(End of file - total 19 lines)
</content>
gateway · 2026-09-03 16:18:25
result
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/src/modules/release-revision.js</path>
<type>file</type>
<content>
1: const CHECK_RUNS_LINK =
2:   /^Requested by: @[^\r\n]+\r?\n(?:[ \t]*\r?\n)?[ \t]*Merge target: [^\r\n]+\r?\n(?:[ \t]*\r?\n)?[ \t]*Quick links:\r?\n(?:[ \t]*\r?\n)?[ \t]*- \[View changes\]\([^\r\n]+\)\r?\n[ \t]*- \[View check runs\]\(https:\/\/github\.com\/getsentry\/(?<repo>[A-Za-z0-9_.-]+)\/commit\/(?<revision>[0-9a-f]{40})\/checks\/?\)(?=\r?\n|$)/;
3: const CHECK_RUNS_LINK_COUNT = /^[ \t]*- \[View check runs\]\(/gm;
4: 
5: function getReleaseRevision({ issueBody, repo }) {
6:   if ((issueBody.match(CHECK_RUNS_LINK_COUNT) || []).length !== 1) {
7:     throw new Error(
8:       `Expected exactly one View check runs link in Quick links for getsentry/${repo}.`
9:     );
10:   }
11: 
12:   const match = issueBody.match(CHECK_RUNS_LINK);
13:   if (!match?.groups || match.groups.repo !== repo) {
14:     throw new Error(
15:       `Expected a View check runs link ...
gateway · 2026-09-03 16:31:45
result
Found 100 matches (more matches available)
/home/byk/Code/getsentry/publish-workspace-acceptance/AGENTS.md:
  Line 186: - **Vitest v4.0.0** with globals enabled

  Line 187: - No need to import `describe`, `test`, `expect` in test files (they're global)


/home/byk/Code/getsentry/publish-workspace-acceptance/docs/publish-issue-format.md:
  Line 13:                     [ legacy-workspace ], "@", version ;

  Line 17: legacy-workspace  = " [workspace: ", json-string, "] " ;

  Line 23: New Craft requests always include the checkout repository identity. Root workspace

  Line 24: releases use one trailing path segment for the workspace name:

  Line 31: Craft rejects a workspace with a non-root checkout path. Workspace names in new titles

  Line 36: `.craft.yml`, `craft workspace list` supplies the exact workspace keys. A suffix that

  Line 37: exactly matches one of those keys is a workspace; every other suffix remains a checkout

  Line 38: path. The controller never normalizes ...
gateway · 2026-09-03 16:43:07
result
diff --git a/src/modules/post-workflow-details.js b/src/modules/post-workflow-details.js
index 278d23e..227c81a 100644
--- a/src/modules/post-workflow-details.js
+++ b/src/modules/post-workflow-details.js
@@ -16,4 +16,4 @@ async function postWorkflowDetails({context, octokit}) {
   });
 }
 
-module.exports = postWorkflowDetails;
\ No newline at end of file
+module.exports = postWorkflowDetails;
diff --git a/src/publish/inputs.js b/src/publish/inputs.js
index 0640d9e..9330d92 100644
--- a/src/publish/inputs.js
+++ b/src/publish/inputs.js
@@ -9,5 +9,4 @@ async function inputs() {
     core.setOutput('result', result);
 }
 
-
-inputs();
\ No newline at end of file
+inputs();
52ef600 feat: resolve compact workspace publish requests
 .github/workflows/ci-poller.yml                |  32 +-
 .github/workflows/publish.yml                  |  65 +-
 docs/publish-issue-format.md                   |  65 +-
 package.json                                   |   5 +-
 ...
gateway · 2026-09-03 16:45:50

Current branch already contains the prior workspace implementation. I confirmed the only uncommitted changes are the two whitespace-only edits you named; I will leave them untouched. The new invariant is: titles carry only a repository path suffix; after the revision checkout, the resolver compares that entire suffix to concrete workspace paths, including glob expansions, and otherwise publishes from that suffix as a checkout path.

gpt-5.6-terra · 2026-09-03 16:45:50 · ~75 tokens
result
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/package.json</path>
<type>file</type>
<content>
1: {
2:   "name": "publish",
3:   "private": true,
4:   "version": "0.0.1",
5:   "description": "Approval-based publishing system for Sentry",
6:   "main": "index.js",
7:   "repository": "git@github.com:getsentry/publish.git",
8:   "author": "Sentry Open Source <oss@sentry.io>",
9:   "license": "Apache-2.0",
10:   "volta": {
11:     "node": "24.0.0",
12:     "yarn": "1.22.22"
13:   },
14:   "resolutions": {
15:     "undici": "^6.23.0"
16:   },
17:   "scripts": {
18:     "generate": "node scripts/generate-publish-issue-title-parser.js",
19:     "check:generated": "node scripts/generate-publish-issue-title-parser.js --check",
20:     "test": "yarn check:generated && vitest run",
21:     "test:watch": "vitest",
22:     "lint": "eslint src .github --ignore-pattern '!.github'",
23:     "prettier": "prettier --write src"
24:   },
25:   "devDependencies": {
26:     "eslint": ...
gateway · 2026-09-03 16:46:01
result
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/src/modules/__tests__/ci-poller-input.js</path>
<type>file</type>
<content>
1: import { readFileSync } from "fs";
2: import { join } from "path";
3: 
4: import { expect, test } from "vitest";
5: 
6: const { getCiPollerInput } = require("../ci-poller-input.js");
7: 
8: const REVISION = "7e5ca7ed5581552de066e2a8bc295b8306be38ac";
9: const issueBody = `Requested by: @byk
10: 
11: Merge target: (default)
12: 
13: Quick links:
14: - [View changes](https://github.com/getsentry/toolkit/compare/1.2.2...release/1.2.3)
15: - [View check runs](https://github.com/getsentry/toolkit/commit/${REVISION}/checks/)`;
16: 
17: test("parses compact and legacy workspace publish titles", () => {
18:   expect(
19:     getCiPollerInput({
20:       issueBody,
21:       title: "publish: getsentry/toolkit/cli@1.2.3",
22:     })
23:   ).toEqual({
24:     repo: "getsentry/toolkit",
25:     revision: REVISION,
26:     version: "1.2.3",
27:   });
28: 
29:   ...
gateway · 2026-09-03 16:46:05
result
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/src/modules/ci-poller-input.js</path>
<type>file</type>
<content>
1: const { parse: parsePublishIssueTitle } = require("./publish-issue-title");
2: const {
3:   getReleaseRevision,
4:   updateReleaseRevision,
5: } = require("./release-revision");
6: 
7: function getCiPollerInput({ title, issueBody, revision }) {
8:   let parsedTitle;
9:   try {
10:     parsedTitle = parsePublishIssueTitle(title);
11:   } catch {
12:     throw new Error(`Invalid publish issue title: '${title}'`);
13:   }
14:   const { repo, version } = parsedTitle;
15:   const currentRevision = getReleaseRevision({ issueBody, repo });
16: 
17:   return {
18:     ...(revision
19:       ? { issueBody: updateReleaseRevision({ issueBody, repo, revision }) }
20:       : {}),
21:     repo: `getsentry/${repo}`,
22:     revision: currentRevision,
23:     version,
24:   };
25: }
26: 
27: module.exports = { getCiPollerInput };

(End of file - total 27 lines)
</content>
gateway · 2026-09-03 16:47:18
result
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/.github/workflows/ci-poller.yml</path>
<type>file</type>
<content>
1: name: CI Status Poller
2: 
3: on:
4:   schedule:
5:     - cron: "*/5 * * * *"
6:   workflow_dispatch:
7:     inputs:
8:       attempt:
9:         description: Self-dispatch attempt counter (internal use)
10:         required: false
11:         default: "0"
12: 
13: permissions:
14:   contents: read
15:   issues: read
16: 
17: jobs:
18:   check-ci:
19:     runs-on: ubuntu-latest
20:     environment: production
21:     # Skip entirely (no runner provisioned) when there's nothing to check.
22:     # Set to "true" by ci-pending.yml, reset to "false" here when done.
23:     # Always allow workflow_dispatch for manual recovery.
24:     if: vars.CI_POLLER_HAS_PENDING == 'true' || github.event_name == 'workflow_dispatch'
25:     concurrency:
26:       group: ci-status-poller
27:       cancel-in-progress: false
28:     steps:
29:       # sentry-internal-app token ...
gateway · 2026-09-03 16:51:15
result
Found 19 matches
/home/byk/Code/getsentry/craft/src/commands/publish.ts:
  Line 16:   expandWorkspaceTargets,

  Line 671:   // Expand any npm workspace targets into individual package targets

  Line 672:   let targetConfigList = await expandWorkspaceTargets(config.targets || []);


/home/byk/Code/getsentry/craft/src/commands/targets.ts:
  Line 1: import { getConfiguration, expandWorkspaceTargets } from '../config';

  Line 12:   // Expand workspace targets (e.g., npm workspaces)

  Line 13:   definedTargets = await expandWorkspaceTargets(definedTargets);


/home/byk/Code/getsentry/craft/src/commands/__tests__/targets.test.ts:
  Line 15:   expandWorkspaceTargets: vi.fn(),

  Line 22: import { getConfiguration, expandWorkspaceTargets } from '../../config';

  Line 27:   const mockedExpandWorkspaceTargets = expandWorkspaceTargets as Mock;

  Line 40:   test('lists targets without expansion when no workspaces', async () => {

  Line 44:     ...
gateway · 2026-09-03 16:53:51
result
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/src/modules/__tests__/publish-workflow.js</path>
<type>file</type>
<content>
1: import { spawnSync } from "child_process";
2: import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "fs";
3: import { tmpdir } from "os";
4: import { join } from "path";
5: 
6: import { afterEach, expect, test } from "vitest";
7: 
8: const { resolvePublishLocation } = require("../publish-location.js");
9: 
10: const temporaryDirectories = [];
11: 
12: function getWorkflow() {
13:   return readFileSync(
14:     join(__dirname, "../../../.github/workflows/publish.yml"),
15:     "utf8"
16:   );
17: }
18: 
19: function getSetTargetsScript() {
20:   const workflow = getWorkflow();
21:   const section = workflow.match(
22:     / {6}- name: Set targets[\s\S]*? {8}run: \|\n(?<script>[\s\S]*?)\n {6}- uses: docker:\/\/getsentry\/craft:latest/
23:   );
24:   if (!section?.groups?.script) {
25:     throw new Error("Missing Set targets workflow ...
gateway · 2026-09-03 16:53:57
result
Found 100 matches (more matches available)
/home/byk/Code/getsentry/craft/src/config.ts:
  Line 27: // Note: We import getTargetByName lazily in expandWorkspaceTargets to avoid

  Line 576: export async function expandWorkspaceTargets(


/home/byk/Code/getsentry/craft/src/utils/workspaces.ts:
  Line 16: export interface WorkspacePackage {

  Line 30: export interface WorkspaceDiscoveryResult {

  Line 34:   packages: WorkspacePackage[];

  Line 38: interface PnpmWorkspaceConfig {

  Line 45:   workspaces?: string[] | { packages?: string[] };

  Line 93:  * Extract workspaces array from package.json workspaces field

  Line 96: function extractWorkspacesGlobs(

  Line 97:   workspaces: string[] | { packages?: string[] } | undefined,

  Line 99:   if (!workspaces) {

  Line 102:   if (Array.isArray(workspaces)) {

  Line 103:     return workspaces;

  Line 105:   return workspaces.packages || [];

  Line 111: async function resolveWorkspaceGlobs(

  Line 114: ): ...
gateway · 2026-09-03 16:54:15
result
Found 8 matches
/home/byk/Code/getsentry/craft/.lore.md:
  Line 55: * **Publish title workspace grammar**: Chose path-based workspace titles with post-checkout, workspace-first resolution over unpublished JSON-qualified workspace syntax or default-branch inference. A title suffix is resolved against exact workspace names from \`craft workspace list\` in the CI-approved checkout, so names such as \`cli/v2\` can be workspaces; otherwise it remains a publish path. The exact approved SHA governs checkout, location, state, \`CRAFT\_WORKSPACE\`, and \`craft publish --rev\`. Discovery failure with root config fails closed rather than silently misrouting a workspace request.

  Line 69: * **action.yml path-based workspace titles**: Craft Action Publish titles identify the checkout repository from \`GITHUB\_REPOSITORY\`; their suffix may be either a path or a workspace name, including slash-containing names such as \`cli/v2\`. ...
gateway · 2026-09-03 16:58:02
result
File not found: /home/byk/Code/getsentry/publish-workspace-acceptance/.lore.md
gateway · 2026-09-03 17:00:52

Distillations (13)

Gen 0 2026-09-03 17:02:04 · 635 tokens

Date: Sep 3, 2026 * 🔴 (16:58) User stated that compact suffix meaning must be resolved only from exact workspace membership in the CI-approved checkout, never by mutating an existing issue. * 🟡 (16:58) Repository search found 8 matches, including `.lore.md`, `craft/src/commands/__tests__/targets.test.ts`, `craft/src/targets/crates.ts`, and `.opencode/plans/workspaces-redesign-design.md`. * 🟡 (…

Gen 0 2026-09-03 16:56:51 · 1316 tokens

Date: Sep 3, 2026 * 🟡 (16:53) Repository search found 19 references to `expandWorkspaceTargets`, including `craft/src/commands/publish.ts` where `targetConfigList = await expandWorkspaceTargets(config.targets || [])` follows the comment “Expand any npm workspace targets into individual package targets”; `craft/src/commands/targets.ts` where `definedTargets = await expandWorkspaceTargets(definedT…

Gen 0 2026-09-03 16:54:09 · 1478 tokens

Date: Sep 3, 2026 * 🔴 (16:51) User stated workflow dispatch must always be allowed for manual recovery. * 🟡 (16:51) `.github/workflows/ci-poller.yml` defines workflow `CI Status Poller`, scheduled every 5 minutes via cron `"*/5 * * * *"`, plus `workflow_dispatch` with optional internal `attempt` input defaulting to `"0"`. * 🟡 (16:51) `CI Status Poller` permissions are `contents: read` and `iss…

Gen 0 2026-09-03 16:48:30 · 925 tokens

Date: Sep 3, 2026 * 🟡 (16:45) Assistant stated that commit `52ef600` (`feat: resolve compact workspace publish requests`) was already present on the current branch and that the only uncommitted changes were whitespace-only newline edits in `src/modules/post-workflow-details.js` and `src/publish/inputs.js`; assistant said these edits would remain untouched. * 🟡 (16:45) Assistant stated a revised…

Gen 0 2026-09-03 16:44:24 · 1251 tokens

Date: Sep 3, 2026 * 🔴 (16:43) User asserted that new Craft requests always include the checkout repository identity. * 🔴 (16:43) User asserted that the controller never normalizes names. * 🟡 (16:43) `docs/publish-issue-format.md` specifies compact publish-title grammar including optional legacy workspace syntax: `legacy-workspace = " [workspace: ", json-string, "] "`; examples include `publish…

Gen 0 2026-09-03 16:34:04 · 391 tokens

Date: Sep 3, 2026 * 🟡 (16:31) `src/modules/release-revision.js` defines `CHECK_RUNS_LINK`, a regex that matches a structured publish-issue Quick links section: `Requested by: @...`, `Merge target: ...`, `Quick links:`, `View changes`, and exactly formatted `View check runs` URL `https://github.com/getsentry/(?<repo>[A-Za-z0-9_.-]+)/commit/(?<revision>[0-9a-f]{40})/checks/?`. It also defines glob…

Gen 0 2026-09-03 16:20:52 · 246 tokens

Date: Sep 3, 2026 * 🟡 (16:17) `src/publish/inputs.js` imports `@actions/github`, `@actions/core`, and `detailsFromContext` from `../modules/details-from-context`. Its `async function inputs()` calls `detailsFromContext({ context: github.context })` and publishes the returned value through `core.setOutput('result', result)`; `inputs()` is invoked immediately. * 🟡 (16:18) `src/modules/post-workfl…

Gen 0 2026-09-03 16:18:25 · 1493 tokens

Date: Sep 3, 2026 * 🟡 (16:10) `src/modules/__tests__/details-from-context.js` completes unsafe legacy-workspace coverage: paragraph separator title `publish: getsentry/toolkit [workspace: "cli\\u2029next"] @1.2.3`, along with empty, multiline, NUL, tab, bidi-format, and line-separator workspace cases, must each reject with `"Workspace names must be nonempty and cannot contain Unicode control, fo…

Gen 0 2026-09-03 16:14:42 · 1477 tokens

Date: Sep 3, 2026 * 🔴 (16:08) User stated that the CI poller always adds `ci-ready` after checking CI; `waiting-for-ci` first removes an existing `ci-ready` label so that the poller’s fresh add emits a `labeled` event and reliably triggers publishing. * 🟡 (16:08) `.github/workflows/publish.yml` has an issue-title concurrency group `${{ github.event.issue.title }}` with `cancel-in-progress: fals…

Gen 0 2026-09-03 16:08:07 · 1551 tokens

Date: Sep 3, 2026 * 🟡 (15:58) Repository file listing confirms workspace-publish implementation artifacts: generator `scripts/generate-publish-issue-title-parser.js`; grammar/parser `src/modules/publish-issue-title.peggy` and `src/modules/publish-issue-title.js`; parsing/validation `src/modules/details-from-context.js`; location resolution `src/modules/publish-location.js` and `src/publish/resol…

Gen 0 2026-09-03 16:00:45 · 931 tokens

Date: Sep 3, 2026 * 🟡 (15:54) Git branch/status in `/home/byk/Code/getsentry/publish-workspace-acceptance`: `feat/workspace-acceptance...origin/feat/workspace-acceptance`; modified files remain `src/modules/post-workflow-details.js` and `src/publish/inputs.js`. * 🟡 (15:54) Recent commits listed: `52ef600 feat: resolve compact workspace publish requests`; `b658ffa fix: validate publish workspace…

Gen 0 2026-09-03 15:55:53 · 170 tokens

Date: Sep 3, 2026 * 🟡 (15:52) Workspace directory `/home/byk/Code/getsentry/publish-workspace-acceptance` contains `.eslintrc.js`, `.git/`, `.github/`, `.gitignore`, `AGENTS.md`, `auto-approve-repos.txt`, `docs/`, `LICENSE`, `node_modules/`, `package.json`, `README.md`, `scripts/`, `src/`, `vitest.config.js`, and `yarn.lock` (15 entries). * 🟡 (15:52) Assistant stated it will first map the exist…

Gen 0 2026-09-03 15:52:04 · 412 tokens

Date: Sep 3, 2026 * 🔴 [enforced-workspace-scope] (15:50) User directed all work be limited to `/home/byk/Code/getsentry/publish-workspace-acceptance`; Craft must not be modified. * 🔴 [requested-implementation] (15:50) User requested implementation of the approved replacement of unpublished JSON workspace titles with path-based full-suffix workspace resolution. * 🔴 (15:50) User specified that t…