Dashboard › craft › Distillation
b1e8b5b9-744f-483b-8959-57d537dda392["lore_tm_v1_Yam_t-NShEKYXhkhIFk8hoZ8PxP1a0gkCZAS7y1x-jE"]
Date: September 8, 2026
.github/workflows/ci-poller.yml changes actions/checkout@v5 to actions/checkout@v7 for the βCheck out publish controllerβ step, retaining checkout path .__publish__..github/workflows/ci-poller.yml refactors per-issue processing in the while read -r issue loop into a subshell (...), replacing invalid continue operations inside command-substitution-related logic with exit 0 to safely skip the current issue without terminating the enclosing poller loop..github/workflows/ci-poller.yml preserves raw issue-body bytes by writing jq -jr '.body' output to body_file=$(mktemp) and passing PUBLISH_ISSUE_BODY_FILE="$body_file" to node .__publish__/src/publish/resolve-ci-poller-input.js, replacing PUBLISH_ISSUE_BODY="$body" shell-variable transport..github/workflows/ci-poller.yml adds an EXIT trap that removes body_file, resolver_output_file, and updated_body_file with rm -f; empty/unset file variables are skipped..github/workflows/ci-poller.yml updates issue bodies only after resolver success and validation: resolver JSON is written to resolver_output_file; jq -ejr 'if (.issueBody | type) == "string" then .issueBody else error("Expected issueBody string") end' writes validated text to updated_body_file; gh issue edit "$number" -R "$GITHUB_REPOSITORY" --body-file "$updated_body_file" performs the edit. Failed resolution or decoding logs a warning and exit 0, so malformed resolver output cannot edit the issue..github/workflows/ci-poller.yml changes skip behavior from continue to exit 0 for canonical-input parse failure, commit-status fetch failure, check-runs fetch failure, and the zero-check/zero-status βCI may not have startedβ condition..github/workflows/publish.yml replaces inline .craft.yml/Docker workspace discovery (getsentry/craft:latest workspace list) with node .__publish__/src/publish/discover-location.js, setting PUBLISH_REPOSITORY_DIRECTORY: __repo__; the previously inline Docker getsentry/craft:latest invocation is removed from this workflow location step.docs/publish-issue-format.md replaces hand-maintained title EBNF with a generated canonical Peggy grammar block delimited by <!-- BEGIN GENERATED TITLE GRAMMAR --> and <!-- END GENERATED TITLE GRAMMAR -->, sourced from src/modules/publish-issue-title.peggy.docs/publish-issue-format.md states that new Craft requests always include checkout repository identity and that a workspace release title uses its full concrete path suffix.docs/publish-issue-format.md changes Merge target from optional to required; (default) remains the default-branch representation and allowed branch characters remain letters, digits, _, ., /, and -.scripts/generate-publish-issue-title-parser.js now generates both src/modules/publish-issue-title.js and the generated documentation grammar in docs/publish-issue-format.md. It exports generateDocumentation, invokes main() only when require.main === module, and uses Peggy start rules PublishIssueTitle, ReleaseRevision, and CheckRunsLinkCount./<!--\s*(?:BEGIN|END)\s+GENERATED\s+TITLE\s+GRAMMAR\b/g; it requires exactly one BEGIN and one END marker and requires one correctly ordered full marker block, otherwise throws Could not find the generated title grammar in the documentation.// BEGIN TITLE GRAMMAR and // END TITLE GRAMMAR; if absent it throws Could not find the publish issue title grammar. In --check mode it separately rejects stale parser output and stale documentation with instructions to run yarn generate; otherwise it writes both files.src/modules/publish-issue-title.peggy marks the canonical title grammar using // BEGIN TITLE GRAMMAR and // END TITLE GRAMMAR, then adds grammar start rule ReleaseRevision to parse the canonical request header strictly from the beginning of the issue body while permitting trailing body content.ReleaseRevision grammar requires the header sequence: Requested by: @ plus nonempty requester; newline/optional blank lines; Merge target: plus valid target; Quick links:; a View changes link; and one canonical View check runs URL matching https://github.com/getsentry/<Repository>/commit/<lowercase-40-char-SHA>/checks with optional terminal /, followed by a line boundary.ReleaseRevision grammar returns { repo, mergeTarget, revision }, where revision includes { value, start, end } source offsets for indexed replacement; merge targets allow (default) or one or more [A-Za-z0-9_./-].CheckRunsLinkCount grammar scans the entire issue body and counts all - [View check runs]( occurrences, including appended decoy links, to enforce global duplicate detection.src/modules/publish-issue-title.js exposes start rules PublishIssueTitle, ReleaseRevision, and CheckRunsLinkCount, implementing the new Peggy grammar and parser source-offset capture.src/modules/release-revision.js replaces regex parsing with parse from ./publish-issue-title. getReleaseRevisionDetails({ issueBody, repo }) first requires parse(issueBody, { startRule: "CheckRunsLinkCount" }) === 1, then parses ReleaseRevision, validates parsed repository identity against repo, and throws canonical-link errors on parse/repository failures.src/modules/release-revision.js adds isRevision(revision) requiring /^[0-9a-f]{40}$/; updateReleaseRevision() rejects any other value with Release revision must be a lowercase 40-character SHA. and replaces only issueBody.slice(currentRevision.start, currentRevision.end), preserving all other bytes.src/modules/release-revision.js exports getReleaseRevisionDetails in addition to getReleaseRevision and updateReleaseRevision.src/modules/details-from-context.js now gets merge-target authority from getReleaseRevisionDetails({ issueBody: context.payload.issue.body || "", repo: titleDetails.repo }) rather than a multiline Merge target regex; it maps canonical (default) to merge_target: "" and returns any other canonical merge target unchanged.src/modules/__tests__/details-from-context.js updates issue fixtures to contain required canonical request headers and adds a test proving an appended Merge target: decoy does not override the canonical headerβs custom-branch.src/modules/__tests__/release-revision.js adds coverage accepting /checks without terminal slash; rejecting a check-runs URL lacking the /checks path; rejecting an appended decoy check-runs link outside the request header; and rejecting uppercase, 39-character, and 41-character replacement revisions.src/modules/__tests__/publish-workflow.js updates expected location-discovery behavior to require node .__publish__/src/publish/discover-location.js and PUBLISH_REPOSITORY_DIRECTORY: __repo__; it continues to reject getsentry/craft:2.31.0 and expects CI-approved revision checkout and CRAFT_PUBLISH_PATH JSON output use.src/publish/resolve-ci-poller-input.js supports PUBLISH_ISSUE_BODY_FILE: when set, it reads UTF-8 body content using readFileSync; otherwise it falls back to PUBLISH_ISSUE_BODY || "".src/publish/resolve-location.js changes absent JSON environment fallbacks from empty strings to valid JSON defaults: PUBLISH_ARGS || "{}" and CRAFT_WORKSPACE_NAMES || "[]"; it JSON-serializes resolvePublishLocation(...) before core.setOutput("result", ...).src/publish/resolve-release-revision.js changes absent PUBLISH_ARGS fallback to "{}" and fails closed with throw new Error("Publish input must define a repository.") when repo is missing.src/publish/inputs.js changes core.setOutput('result', result) to core.setOutput('result', JSON.stringify(result)), ensuring structured publish input is serialized as JSON; the file now ends with a newline.