Dashboard › craft › Distillation
6e44f210-a4b5-4eda-8af8-3d9e8af3d39b["lore_tm_v1_ZpbOi4kWRaCGq2lhdodjALKrNaI1SWkvyMaGVpazdhE"]
Date: Sep 8, 2026
.github/workflows/ci-poller.yml checkout from actions/checkout@v5 to actions/checkout@v7, and .github/workflows/publish.yml controller and target-repository checkouts from actions/checkout@v6 to actions/checkout@v7..github/workflows/ci-poller.yml now processes each issue in a subshell within its while read -r issue loop, enabling per-issue EXIT cleanup. It writes .body from the JSON issue object to body_file=$(mktemp) with jq -jr, passes PUBLISH_ISSUE_BODY_FILE="$body_file" instead of body content through PUBLISH_ISSUE_BODY, and removes body_file, resolver_output_file, and updated_body_file via trap ... EXIT.continue to exit 0 because each issue runs in its own subshell: canonical-input parse failure, commit-status fetch failure, check-runs fetch failure, and zero check/status counts now exit only the current issue subshell.resolve-ci-poller-input.js output is written to resolver_output_file; jq -ejr 'if (.issueBody | type) == "string" and (.issueBody | length) > 0 then .issueBody else error("Expected nonempty issueBody string") end' produces updated_body_file; gh issue edit ... --body-file "$updated_body_file" edits the issue. Parse/decode failures emit warnings and exit the current subshell..github/workflows/publish.yml replaces inline Docker/Craft workspace enumeration (getsentry/craft:latest workspace list, conditional on __repo__/.craft.yml) with node .__publish__/src/publish/discover-location.js, passing PUBLISH_ARGS: ${{ steps.inputs.outputs.result }} and PUBLISH_REPOSITORY_DIRECTORY: __repo__.docs/publish-issue-format.md replaces manually maintained EBNF title documentation with a generated Peggy grammar block delimited by <!-- BEGIN GENERATED TITLE GRAMMAR --> and <!-- END GENERATED TITLE GRAMMAR -->; canonical PublishIssueTitle accepts optional getsentry/, repository/path tokens [A-Za-z0-9_.-], and version tokens [A-Za-z0-9_.+-].Merge target required rather than optional; (default) still denotes the target repositoryβs default branch, and branch characters remain letters, digits, _, ., /, and -.scripts/generate-publish-issue-title-parser.js now generates both src/modules/publish-issue-title.js and the title-grammar block in docs/publish-issue-format.md. Peggy generation permits start rules PublishIssueTitle, ReleaseRevision, and CheckRunsLinkCount; --check errors separately when either parser or documentation is stale; the module exports generateDocumentation.generateDocumentation({ documentation, titleGrammar }) validates exactly one BEGIN and one END generated-title-grammar marker, replaces the marker-bounded block with fenced peggy grammar content, and throws Could not find the generated title grammar in the documentation. if marker validation/replacement fails.src/modules/publish-issue-title.peggy now marks the canonical title grammar with // BEGIN TITLE GRAMMAR / // END TITLE GRAMMAR and adds parsers for issue-body release metadata: ReleaseRevision, RequestHeader, CheckRunsRevision, CheckRunsLinkCount, CheckRunsLink, Indent, BlankLines, LineBoundary, Newline, NonNewline, MergeTarget, and LinkDestination.RequestHeader grammar requires the bodyβs initial canonical sequence: Requested by: @...; Merge target: <(default) or [A-Za-z0-9_./-]+>; Quick links:; a View changes link; and exactly formatted https://github.com/getsentry/<repo>/commit/<40 lowercase hex SHA>/checks link with optional trailing /. It captures repository, merge target, and revision offsets for safe replacement.CheckRunsLinkCount scans the entire issue body and counts occurrences of - [View check runs](, protecting canonical request parsing from appended decoy check-runs links.src/modules/release-revision.js replaces regex constants CHECK_RUNS_LINK and CHECK_RUNS_LINK_COUNT with the generated Peggy parse function from ./publish-issue-title. New getReleaseRevisionDetails({ issueBody, repo }) first requires CheckRunsLinkCount === 1, parses the initial ReleaseRevision header, validates header repository equality, and returns { repo, mergeTarget, revision }.getReleaseRevision({ issueBody, repo }) now returns getReleaseRevisionDetails(...).revision.value. updateReleaseRevision({ issueBody, repo, revision }) validates /^[0-9a-f]{40}$/, throws Release revision must be a lowercase 40-character SHA. on invalid replacement, and replaces only the captured revision byte range, preserving all surrounding body content including CRLF/trailing content.src/modules/details-from-context.js now calls getReleaseRevisionDetails({ issueBody: context.payload.issue.body || "", repo: titleDetails.repo }) rather than independently regex-parsing Merge target; resulting merge_target is "" for "(default)" and otherwise the canonical headerβs mergeTarget, preventing appended Merge target: decoys from overriding it.src/publish/inputs.js changes core.setOutput('result', result) to core.setOutput('result', JSON.stringify(result)).src/publish/resolve-location.js now defaults PUBLISH_ARGS to "{}" and CRAFT_WORKSPACE_NAMES to "[]", and JSON-stringifies resolvePublishLocation({ path: input.path, workspaceNames }) before setting the result output.src/publish/resolve-release-revision.js now defaults PUBLISH_ARGS to "{}" and throws Publish input must define a repository. if parsed repo is absent.src/publish/resolve-ci-poller-input.js now supports file-backed input: if PUBLISH_ISSUE_BODY_FILE is defined it uses readFileSync(..., "utf8"); otherwise it falls back to PUBLISH_ISSUE_BODY || "".src/modules/publish-issue-title.js was regenerated to expose StartRules: ["PublishIssueTitle", "ReleaseRevision", "CheckRunsLinkCount"] and implement the new release-revision/header/link-count grammar.src/modules/__tests__/details-from-context.js: issue bodies now include canonical request headers and check-runs links; a test verifies an appended Merge target: decoy does not override canonical custom-branch; workspace-path title test uses publish: getsentry/toolkit/packages/cli@1.2.3 with canonical body metadata.src/modules/__tests__/release-revision.js: accepts check-runs URLs without trailing slash; rejects URLs lacking /checks; rejects an embedded second check-runs link outside request header; verifies CRLF/trailing-content preservation when replacing the canonical SHA; rejects replacement SHAs of uppercase 40 characters, 39 lowercase characters, and 41 lowercase characters.src/modules/__tests__/publish-workflow.js now expects exactly 2 actions/checkout@v7 usages, node .__publish__/src/publish/discover-location.js, and PUBLISH_REPOSITORY_DIRECTORY: __repo__; it no longer expects getsentry/craft:latest workspace list or the .craft.yml conditional, while retaining assertions that the CI-approved revision is used for checkout, location resolution, and publishing.