Dashboard › publish › Distillation
1dd0c8bd-3abf-4b96-b2d6-bce6d349eedc["lore_tm_v1_f7RZYEgSGdMqED9sxjtbStRMRTwfxyM8BJO6fbqXZ8g","lore_tm_v1_y5tt_5q3OFKzVBKFYLhVJAdpMqZXVJsruworKV0-OKQ","lore_tm_v1_dZXqU7kbzy2k1tyJ2pmM56MvsYLec7-OyDhQ-0Z657U","lore_tm_v1_8m_gujbZSuIQ-gP9uFZuDartQVna5M0tAOJh9DUfGjs","lore_tm_v1_h--w0brAoFkSP0H8UtA-UWIwcd7cWJkJadsoMT7aUCQ","lore_tm_v1_fqHVJLQB-1TsPCf1UWf14-Jlgd4aerdwTt0c1KTuNaI","lore_tm_v1_9aglYlAAHnJZWF5WuKZnRgKg2xbYptaRZWDmMDUbe8k","lore_tm_v1_aRUrfgwUl8qZ040uIk2h_HBfmqC4gdqfTrAa5sncSYU"]
π΄ (12:04) /home/byk/Code/getsentry/publish/src/modules/__tests__/process-end-state.js tests processEndState() for statuses "failure", "cancelled", "success", and undefined using repository sentry, version 21.3.1, run ID "1234", and publish issue "211".
π΄ (12:04) For status "failure", processEndState() creates exactly 1 issue comment beginning Failed to publish. with run logs URL https://github.com/getsentry/sentry/actions/runs/1234?check_suite_focus=true#step:8 and a branch-deletion link querying 21.3.1.
π΄ (12:04) For status "cancelled", processEndState() creates exactly 1 issue comment beginning Publish workflow cancelled. with the same run logs and branch-deletion links used for failure.
π΄ (12:04) For status "success", processEndState() creates exactly 1 comment Published successfully: [run#1234](https://github.com/getsentry/sentry/actions/runs/1234) and closes issue "211" by updating its state to "closed".
π΄ (12:04) processEndState() must close a successfully published issue before calling getWorkflowRun() or creating the success comment; the test confirms closure still happens when workflow lookup rejects with "unavailable".
π΄ (12:04) processEndState() rejects undefined status with Unknown status: 'undefined' and performs neither createComment nor issue update.
π΄ (12:04) /home/byk/Code/getsentry/publish/src/modules/__tests__/update-issue.js tests updateIssue() and transformIssueBody().
π΄ (12:04) updateIssue() uses CRAFT_STATE_FILE_PATH from the workflowβs secure state-file output; the tested path is .craft-state/craft/publish-state-getsentry-sentry-c232c383e26f-21.3.1.json.
π΄ (12:04) When the Craft state file exists, updateIssue() reads published state { lol: true, hey: false, github: true }, fetches publish issue "211", and updates targets to include - [x] github, - [ ] pypi, - [x] lol, and - [ ] hey.
π΄ (12:04) When the Craft state file does not exist, updateIssue() does not modify the issue body.
π΄ (12:04) updateIssue() removes the "accepted" label exactly once from issue "211" whether or not the Craft state file exists.
π΄ (12:04) When CRAFT_STATE_FILE_PATH is absent because target setup was skipped, updateIssue() does not call fs.existsSync() and does not update the issue body.
π΄ (12:04) updateIssue() removes "accepted" even when parsed publish inputs are absent; in that case it performs no state-file existence check, issue fetch, or issue-body update.
π΄ (12:04) transformIssueBody() replaces the existing Targets section according to Craft state while preserving the surrounding request body: tested state marks "npm[@sentry/node]", "aws-lambda", and "foo" checked, and "github" unchecked, in that order.
π΄ (12:05) /home/byk/Code/getsentry/publish/src/libs/__tests__/github.js tests getGitHubToken(): it throws No "GITHUB_TOKEN" environment variable found. when GITHUB_TOKEN is absent and returns the environment variable unchanged when defined.
π΄ (12:05) /home/byk/Code/getsentry/publish/src/publish/__tests__/resolve-release-revision.js verifies resolve-release-revision.js handles empty PUBLISH_ARGS and PUBLISH_ISSUE_BODY by failing with Publish input must define a repository. rather than leaking the parser error Unexpected end of JSON input.
π΄ (12:05) /home/byk/Code/getsentry/publish/README.md describes the release flow in order: 1. developer triggers release workflow, 2. SDK repository runs craft prepare, 3. artifacts are built and a release branch is created, 4. artifacts are uploaded to GitHub, 5. an issue is created in getsentry/publish, 6. a release manager reviews it, 7. adding "accepted" triggers publishing, 8. artifacts are downloaded from GitHub, 9. craft publish publishes to registries, 10. success closes the issue while failure updates it.
π΄ (12:05) The repositoryβs stated goals are: 1. employees do not publish through personal accounts, 2. employees cannot access global credentials, 3. releases are not built or published from employee machines, 4. releases require formal approval by a limited set of release managers, and 5. these controls should not discourage any engineer from initiating a release.
π΄ (12:05) Publish usage is: 1. trigger the workflow in the source repository, 2. find the resulting request in getsentry/publish, 3. add the "accepted" label, requesting help from a team lead or manager if elevated permissions are needed, 4. observe the issue for run information, and 5. allow the issue to close automatically after successful publishing.
π΄ (12:05) CalVer configuration in .craft.yml uses versioning.policy: calver, calver.format: "%y.%-m" (for example 24.12 for December 2024), and optional calver.offset: 14.
π΄ (12:05) Releases merge into the target repositoryβs default branch, usually master or main, unless the release workflow supplies merge_target; the documented reusable workflow is getsentry/craft/.github/workflows/release.yml@v2 with version, merge_target, and secrets: inherit.
π΄ (12:05) Customer-installed public packages such as sentry-cli, SDKs, and distributed symbolicator utilities require explicit approval; internal dependencies such as arroyo may use automatic approval because their later dependency bump in Sentry proper requires another explicit approval.
π΄ (12:05) Automatic approvals are managed in .github/workflows/auto-approve.yml; the documentation notes that an independently used package may need auto-approval reconsidered if it becomes an attractive attack target.
π΄ (12:05) Secret-bearing jobs use the protected production environment, which allows only main deployments and forbids administrator bypass, protecting environment-scoped credentials from arbitrary workflow refs.
π΄ (12:05) SENTRY_INTERNAL_APP_PRIVATE_KEY and SENTRY_RELEASE_BOT_PRIVATE_KEY are organization-level secrets whose availability boundary must be managed separately by Security.
π΄ (12:05) The system uses Craft and short-lived tokens from the Sentry Release Bot GitHub App via actions/create-github-app-token; the app is installed across getsentry repositories with read/write access to code, pull requests, and actions.
π΄ (12:05) Craft GitHub Actions cannot use GITHUB_TOKEN to create publish requests because GitHub prevents workflows triggered with that token from triggering additional workflows.
π΄ (12:06) /home/byk/Code/getsentry/publish/docs/key_rotation_vault_changes.md identifies 3 existing secret vaults: 1. SDKs/OSS, available to a range of employees including some who departed; 2. Shared, available to all engineers including some who departed; 3. Ops, available to operations with no departed users.
π΄ (12:06) The proposed dedicated-service credential model uses a configured machine notified by GitHub Actions about project/version releases, stores all publishing credentials on that machine, and allows an authorized person to press a publish button or permits automatic publication when allowed.
π΄ (12:06) The proposed separate-repository model is: 1. centralize release actions in one restricted repository, 2. grant admin/write access only to bare-minimum personnel, 3. expose credentials only to that repository, 4. restrict release tokens to a few people, 5. let others request releases through structured issues and issue-based workflows with read access, and 6. optionally auto-create release requests when a release/* branch is pushed.
π΄ (12:06) Proposed credential reorganization places these keys in OSS: PyPI Bot, Crates.io, DockerHub, GitHub getsentry-bot, NPM Bot, Cocoapods, Nexus, Packagist, RubyGems, Code Signing Certificate, Bintray, Bot Apple ITC, and clojars.org; remaining SDK-vault items go to SDK Low Security, available to the SDK Team.
π΄ (12:06) /home/byk/Code/getsentry/publish/docs/rfc.md states the central repository addresses rapid recycling of NPM, PyPI, Cargo, Docker, and other publishing tokens; restriction of token access; mandatory manager or senior-engineer approval for SDK releases under SOC/ISO policy; and elimination of divergent per-project release configurations.
π΄ (12:06) The RFCβs proposed process is: 1. create a central release/publish repository containing workflows and tokens, 2. grant write/admin/triage only to authorized personnel, 3. grant other engineers read access, 4. use a structured release-request issue, 5. have each repository run craft prepare and open an issue containing repository name and version, 6. have central-repository owners add "accepted" to trigger release, 7. close the issue with a success message, and 8. auto-approve OSS CalVer releases unless a release blocker exists.
π΄ (12:06) User stated release approvals should always require a second person, like a code review.
π΄ (12:06) The central publish RFC records additional design questions about whether release-repository owners can run publishing directly, how much friction the process causes, whether approval rights should be project-specific, and whether exposing all tokens to all authorized personnel is acceptable.
π΄ (12:06) /home/byk/Code/getsentry/publish/AGENTS.md defines the project as a pure JavaScript GitHub Actions approval system running Node.js 24.0.0, with CommonJS source modules.
π΄ (12:06) The repository requires Yarn 1.22.22 via Volta and explicitly forbids npm; commands are yarn install, yarn test, yarn test:watch, yarn test src/modules/__tests__/update-issue.js, yarn test -t "pattern", yarn lint, and yarn prettier.
π΄ (12:06) Single-test command forms are: by path, yarn test src/modules/__tests__/update-issue.js; by name, yarn test -t "transformIssueBody"; and combined, yarn test src/modules/__tests__/update-issue.js -t "specific test name".
π΄ (12:06) Project layout assigns src/libs/ to shared helpers, src/modules/ to reusable core business logic, and src/publish/ to GitHub Actions entry points.
π΄ (12:06) Repository style requires kebab-case file names, matching tests under __tests__/, camelCase variables/functions, and UPPER_SNAKE_CASE constants and regex patterns.
π΄ (12:06) Source files use CommonJS require/module.exports; tests use ES module import/export; named CommonJS exports are preferred when exporting multiple functions.
π΄ (12:06) Import ordering is Node.js built-ins first, external packages second, and relative local modules third.
π΄ (12:06) Formatting uses Prettier defaults, double-quoted strings, required semicolons, and yarn prettier before committing.
π΄ (12:06) Error handling requires early guard clauses and descriptive errors containing context and possible fixes.
π΄ (12:06) User stated unexpected values must always throw; switch statements must include a default branch such as throw new Error(\Unknown status: '${status}'`). π΄ (12:06) Files must be checked with fs.existsSync(CRAFT_STATE_FILE_PATH)before being read. π΄ (12:06) Tests use Vitestv4.0.0with globals enabled and automatically cleared mocks; external dependencies should be mocked before requiring the module under test, and inline snapshots are recommended for complex output. π΄ (12:06) Key dependencies are@actions/corefor GitHub Actions inputs, outputs, and logging;@actions/githubfor API access; and@sentry/nodefor error reporting. π΄ (12:06) Common repository patterns includePromise.all()for parallel async operations, object destructuring, spread-based object merging, template literals, and regular expressions with named groups. π΄ (12:06) All repository code is owned by@getsentry/releng; long-term agent-managed project knowledge is stored in .lore.mdvialore (https://github.com/BYK/loreai`).