Dashboard › craft › Session 1bnaiQoZ3c3e
1bnaiQoZ3c3e1xzbGPerform a strict, read-only adversarial review of Craft PR #872 at exact head f174ceafa57355e71617f32ba1b0a030953be0a2 in /home/byk/Code/getsentry/craft-workspace-action-propagation, against origin/master. Do not edit, format, commit, or mutate files. Inspect every changed file and relevant code/tests/docs. Verify: concrete slash-containing workspace paths are preserved as exact POSIX identities, safe segment validation rejects traversal/prototype/option-like/unsafe values, glob/brace expansion fails closed and has lexical+realpath containment, config-from workspace root works, action validation before side effects/ambient workspace clear/full path title, workspace state identity, and no regressions in release behavior. Check the renamed test represents concrete multi-segment workspace paths rather than legacy compatibility. Run only non-mutating checks if essential. Report severity-ranked file:line findings, explicit PASS/FAIL checks, test gaps, exact-head/diff hygiene evidence, ending exactly MERGE or DO-NOT-MERGE.
f174ceafa57355e71617f32ba1b0a030953be0a2 21270a1d12a60b461c51fba93bd076b90d9cf4af 21270a1d12a60b461c51fba93bd076b90d9cf4af M .github/workflows/release.yml M action.yml M docs/src/content/docs/targets/github.md A src/__tests__/action.test.ts M src/__tests__/config.test.ts M src/commands/__tests__/publish.test.ts M src/commands/prepare.ts M src/commands/publish.ts A src/commands/workspace.ts A src/commands/workspace_cmds/__tests__/list.test.ts A src/commands/workspace_cmds/list.ts M src/config.ts M src/index.ts M src/schemas/project_config.ts M src/utils/__tests__/publishState.test.ts M src/utils/publishState.ts
f174cea (HEAD -> feat/workspace-action-propagation, origin/feat/workspace-action-propagation) test: describe workspace paths accurately d48b906 feat: support concrete release workspaces 4862056 feat: support compact release workspaces 6dae341 feat: propagate release workspaces .github/workflows/release.yml | 9 + action.yml | 40 ++- docs/src/content/docs/targets/github.md | 42 ++- src/__tests__/action.test.ts | 313 ++++++++++++++++++++ src/__tests__/config.test.ts | 324 ++++++++++++++++++--- src/commands/__tests__/publish.test.ts | 74 +++++ src/commands/prepare.ts | 3 +- src/commands/publish.ts | 51 +++- src/commands/workspace.ts | 13 + src/commands/workspace_cmds/__tests__/list.test.ts | 31 ++ src/commands/workspace_cmds/list.ts | 9 + ...
<path>/home/byk/Code/getsentry/craft-workspace-action-propagation/src/schemas/project_config.ts</path>
<type>file</type>
<content>
1: import { z } from 'zod';
2: import { hasMagic } from 'glob';
3:
4: /**
5: * DEPRECATED: Use changelog.policy instead. Different policies for changelog management
6: */
7: export const enum ChangelogPolicy {
8: Auto = 'auto',
9: Simple = 'simple',
10: None = 'none',
11: }
12:
13: /**
14: * Name of the status provider
15: */
16: export const enum StatusProviderName {
17: GitHub = 'github',
18: }
19:
20: /**
21: * Name of the artifact provider
22: */
23: export const enum ArtifactProviderName {
24: GCS = 'gcs',
25: GitHub = 'github',
26: None = 'none',
27: }
28:
29: /**
30: * Default versioning policy when no version argument is provided. ...
<path>/home/byk/Code/getsentry/craft-workspace-action-propagation/src/config.ts</path>
<type>file</type>
<content>
1: import { existsSync, lstatSync, readFileSync, realpathSync } from 'fs';
2: import path from 'path';
3: import { globSync, hasMagic } from 'glob';
4:
5: import { load } from 'js-yaml';
6: import GitUrlParse from 'git-url-parse';
7: import { createGitClient } from './utils/git';
8: import { ZodError } from 'zod';
9:
10: import { logger } from './logger';
11: import {
12: CraftProjectConfig,
13: CraftProjectConfigSchema,
14: GitHubGlobalConfig,
15: ArtifactProviderName,
16: StatusProviderName,
17: TargetConfig,
18: ChangelogPolicy,
19: VersioningPolicy,
20: Workspace,
21: } from './schemas/project_config';
22: import { ConfigurationError } from './utils/errors';
23: import { isCompiledGitHubAction } from './utils/detection';
24: import {
25: getPackageVersion,
26: parseVersion,
27: versionGreaterOrEqualThan,
28: SemVer,
29: } from ...
<path>/home/byk/Code/getsentry/craft-workspace-action-propagation/src/commands/workspace.ts</path>
<type>file</type>
<content>
1: import { Argv, CommandBuilder } from 'yargs';
2:
3: import * as list from './workspace_cmds/list';
4:
5: export const command = ['workspace <command>'];
6: export const description = 'Manage release workspaces';
7:
8: export const builder: CommandBuilder = (yargs: Argv) =>
9: yargs.demandCommand().command(list);
10:
11: export const handler = (): void => {
12: /* pass */
13: };
(End of file - total 13 lines)
</content>
<path>/home/byk/Code/getsentry/craft-workspace-action-propagation/src/commands/workspace_cmds/list.ts</path>
<type>file</type>
<content>
1: import { getWorkspaceNames } from '../../config';
2: import { formatJson } from '../../utils/strings';
3:
4: export const command = ['list'];
5: export const description = 'List defined release workspaces as a JSON array';
6:
7: export function handler(): void {
8: console.log(formatJson(getWorkspaceNames()));
9: }
(End of file - total 9 lines)
</content>
<path>/home/byk/Code/getsentry/craft-workspace-action-propagation/src/index.ts</path>
<type>file</type>
<content>
1: #!/usr/bin/env node
2: // Import Sentry instrumentation first, before any other code
3: import './instrument';
4:
5: import isCI from 'is-ci';
6: import yargs from 'yargs';
7:
8: import { logger, LogLevel } from './logger';
9: import {
10: sanitizeDynamicLinkerEnv,
11: warnIfCraftEnvFileExists,
12: } from './utils/env';
13: import {
14: envToBool,
15: setGlobals,
16: extractWorkspaceSelection,
17: } from './utils/helpers';
18: import { getPackageVersion } from './utils/version';
19: import { withTracing } from './utils/tracing';
20: import { setActiveWorkspace } from './config';
21:
22: // Commands
23: import * as prepare from './commands/prepare';
24: import * as publish from './commands/publish';
25: import * as targets from './commands/targets';
26: import * as config from './commands/config';
27: import * as artifacts from './commands/artifacts';
28: ...
Found 21 matches
/home/byk/Code/getsentry/craft-workspace-action-propagation/src/utils/helpers.ts:
Line 42: export function extractWorkspaceSelection(
Line 94: export function setGlobals(argv: GlobalFlags): void {
/home/byk/Code/getsentry/craft-workspace-action-propagation/src/index.ts:
Line 16: extractWorkspaceSelection,
Line 98: // of truth for the selection (see extractWorkspaceSelection for precedence).
Line 99: setActiveWorkspace(extractWorkspaceSelection(argv));
/home/byk/Code/getsentry/craft-workspace-action-propagation/src/utils/__tests__/helpers.test.ts:
Line 10: extractWorkspaceSelection,
Line 37: describe('extractWorkspaceSelection', () => {
Line 42: extractWorkspaceSelection(['publish', '1.0.0'], NO_ENV),
Line 48: extractWorkspaceSelection(['publish', '--workspace', 'cli'], NO_ENV),
Line 53: expect(extractWorkspaceSelection(['--workspace=mcp'], NO_ENV)).toBe('mcp');
Line 57: ...
<path>/home/byk/Code/getsentry/craft-workspace-action-propagation/src/utils/helpers.ts</path>
<type>file</type>
<content>
1: import { appendFileSync, mkdirSync, writeFileSync } from 'fs';
2: import path from 'path';
3: import { parseArgs } from 'node:util';
4:
5: import prompts from 'prompts';
6: import { logger, LogLevel, setLevel } from '../logger';
7:
8: /**
9: * Maximum size (in bytes) for step output values passed through GITHUB_OUTPUT.
10: * Values exceeding this are truncated to avoid E2BIG errors when GitHub Actions
11: * expands them into environment variables for subsequent steps.
12: *
13: * 64 KB is well under the ~2 MB ARG_MAX kernel limit and also under GitHub's
14: * ~65 536-character issue body limit, so truncated changelogs still render. ...
<path>/home/byk/Code/getsentry/craft-workspace-action-propagation/src/commands/publish.ts</path>
<type>file</type>
<content>
1: import { Arguments, Argv, CommandBuilder } from 'yargs';
2: import chalk from 'chalk';
3: import { existsSync, mkdirSync, readFileSync } from 'fs';
4:
5: import { safeFs } from '../utils/dryRun';
6: import { dirname, join } from 'path';
7: import * as shellQuote from 'shell-quote';
8: import stringLength from 'string-length';
9:
10: import {
11: getConfiguration,
12: getStatusProviderFromConfig,
13: getArtifactProviderFromConfig,
14: DEFAULT_RELEASE_BRANCH_NAME,
15: getGlobalGitHubConfig,
16: expandWorkspaceTargets,
17: getNoMergeConfig,
18: getActiveWorkspace,
19: } from '../config';
20: import { formatTable, logger } from '../logger';
21: import {
22: type GitHubGlobalConfig,
23: TargetConfig,
24: } from '../schemas/project_config';
25: import { getAllTargetNames, getTargetByName, SpecialTarget } from '../targets';
26: import { ...
<path>/home/byk/Code/getsentry/craft-workspace-action-propagation/action.yml</path>
<type>file</type>
<content>
1: name: 'Craft Prepare Release'
2: description: 'Prepare a new release using Craft'
3:
4: inputs:
5: version:
6: description: >
7: Version to release. Can be a semver string (e.g., "1.2.3"),
8: a bump type ("major", "minor", "patch"), or "auto" for automatic detection.
9: required: false
10: merge_target:
11: description: Target branch to merge into. Uses the default branch as a fallback. ...
<path>/home/byk/Code/getsentry/craft-workspace-action-propagation/src/commands/prepare.ts</path>
<type>file</type>
<content>
1: import { existsSync, promises as fsPromises } from 'fs';
2: import { join, relative } from 'path';
3:
4: import * as shellQuote from 'shell-quote';
5: import type { SimpleGit, StatusResult } from 'simple-git';
6: import type { Arguments, Argv, CommandBuilder } from 'yargs';
7: import { createDryRunIsolation, safeFs } from '../utils/dryRun';
8:
9: import {
10: CONFIG_FILE_NAME,
11: DEFAULT_RELEASE_BRANCH_NAME,
12: getConfigFileDir,
13: getConfiguration,
14: getGitTagPrefix,
15: getGlobalGitHubConfig,
16: getVersioningPolicy,
17: loadConfigurationFromString,
18: requiresMinVersion,
19: } from '../config';
20: import { logger } from '../logger';
21: import {
22: ChangelogPolicy,
23: type TargetConfig,
24: VersioningPolicy,
25: } from '../schemas/project_config';
26: import { sleep } from '../utils/async';
27: import {
28: type ...
<path>/home/byk/Code/getsentry/craft-workspace-action-propagation/src/__tests__/action.test.ts</path>
<type>file</type>
<content>
1: import {
2: chmodSync,
3: mkdtempSync,
4: mkdirSync,
5: readFileSync,
6: rmSync,
7: writeFileSync,
8: } from 'fs';
9: import { tmpdir } from 'os';
10: import { join } from 'path';
11: import { spawnSync } from 'child_process';
12:
13: import { load } from 'js-yaml';
14: import { afterEach, expect, test } from 'vitest';
15:
16: interface ActionStep {
17: env?: Record<string, string>;
18: name?: string;
19: run?: string;
20: }
21:
22: function getActionSteps(): ActionStep[] {
23: const action = load(
24: readFileSync(join(__dirname, '../../action.yml'), 'utf8'),
25: ) as {
26: runs?: { steps?: ActionStep[] };
27: };
28: return action.runs?.steps || [];
29: }
30:
31: function getActionStep(name: string): ActionStep {
32: const step = getActionSteps().find(step => step.name === name);
33: if (!step?.run) {
34: ...
<path>/home/byk/Code/getsentry/craft-workspace-action-propagation/src/__tests__/config.test.ts</path>
<type>file</type>
<content>
1: import { describe, test, expect, vi, afterEach, beforeEach } from 'vitest';
2: import { mkdtempSync, mkdirSync, rmSync, symlinkSync, writeFileSync } from 'fs';
3: import { tmpdir } from 'os';
4: import { join } from 'path';
5: /**
6: * Tests of our ability to read craft config files. (This is NOT general test
7: * configuration).
8: */
9:
10: import {
11: getGitTagPrefix,
12: loadConfigurationFromString,
13: validateConfiguration,
14: setActiveWorkspace,
15: getActiveWorkspace,
16: getConfiguration,
17: getVersioningPolicy,
18: getWorkspaceNames,
19: WORKSPACES_MIN_VERSION,
20: } from '../config';
21: import { CraftProjectConfigSchema } from '../schemas/project_config';
22: import { logger } from '../logger';
23:
24: describe('validateConfiguration', () => {
25: test('parses minimal configuration', () => {
26: const data = { ...
<path>/home/byk/Code/getsentry/craft-workspace-action-propagation/src/utils/publishState.ts</path> <type>file</type> <content> 1: /** 2: * Helpers for locating Craft's publish-state file in a path that is NOT 3: * writable by the repository being published. 4: * 5: * Background: `craft publish` writes a small JSON file listing targets 6: * that have completed so a resumed run can skip them. Before this module 7: * existed, the file lived at `.craft-publish-<version>.json` in the 8: * project's cwd. That path is inside the repository checkout, so any 9: * committed file at the same path (or any earlier CI step) could 10: * pre-populate the "published" set and trick Craft into silently 11: * skipping targets. 12: * 13: * The file now lives under `$XDG_STATE_HOME/craft/` (falling back to 14: * `$HOME/.local/state/craft/`). The filename is keyed on 15: * owner, repo, a hash of cwd (to disambiguate monorepo subpaths), and 16: * the version being published. ...
<path>/home/byk/Code/getsentry/craft-workspace-action-propagation/src/utils/__tests__/publishState.test.ts</path>
<type>file</type>
<content>
1: import { describe, test, expect, beforeEach, afterEach } from 'vitest';
2: import { homedir } from 'os';
3: import { join } from 'path';
4:
5: import {
6: getCraftStateDir,
7: getPublishStateFilename,
8: getPublishStatePath,
9: } from '../publishState';
10:
11: describe('publishState', () => {
12: const savedEnv = { ...process.env };
13:
14: beforeEach(() => {
15: delete process.env.XDG_STATE_HOME;
16: });
17:
18: afterEach(() => {
19: process.env = { ...savedEnv };
20: });
21:
22: describe('getCraftStateDir', () => {
23: test('defaults to $HOME/.local/state/craft when XDG_STATE_HOME is unset', () => {
24: expect(getCraftStateDir()).toBe(
25: join(homedir(), '.local', 'state', 'craft'),
26: );
27: });
28:
29: test('honours XDG_STATE_HOME when set', () => {
30: ...
<path>/home/byk/Code/getsentry/craft-workspace-action-propagation/src/commands/__tests__/publish.test.ts</path>
<type>file</type>
<content>
1: import { vi, describe, test, expect, beforeEach, type Mock } from 'vitest';
2: import { join as pathJoin } from 'path';
3: import { spawnProcess, hasExecutable } from '../../utils/system';
4: import {
5: getPublishStateGitHubConfig,
6: getRevisionBranchName,
7: runPostReleaseCommand,
8: handleReleaseBranch,
9: MergeConflictError,
10: PushError,
11: } from '../publish';
12: import { getPublishStateFilename } from '../../utils/publishState';
13: import type { SimpleGit } from 'simple-git';
14:
15: vi.mock('../../utils/system');
16: vi.mock('../../utils/git', () => ({
17: getDefaultBranch: vi.fn().mockResolvedValue('main'),
18: getGitClient: vi.fn(),
19: isRepoDirty: vi.fn(),
20: findReleaseBranches: vi.fn(),
21: }));
22:
23: describe('runPostReleaseCommand', () => {
24: const newVersion = '2.3.4';
25: const ...
<path>/home/byk/Code/getsentry/craft-workspace-action-propagation/src/commands/workspace_cmds/__tests__/list.test.ts</path>
<type>file</type>
<content>
1: import { describe, expect, test, vi } from 'vitest';
2:
3: vi.mock('../../../config', () => ({
4: getWorkspaceNames: vi.fn(),
5: }));
6: vi.mock('../../../utils/strings', () => ({
7: formatJson: vi.fn(value => JSON.stringify(value)),
8: }));
9:
10: import { getWorkspaceNames } from '../../../config';
11: import { handler } from '../list';
12:
13: describe('workspace list command', () => {
14: test('prints exact configured workspace names', () => {
15: vi.mocked(getWorkspaceNames).mockReturnValue(['cli', 'mcp.v2']);
16: const log = vi.spyOn(console, 'log').mockImplementation(() => {});
17:
18: handler();
19:
20: expect(log).toHaveBeenCalledWith('["cli","mcp.v2"]');
21: });
22:
23: test('prints an empty array when no workspaces are configured', () => {
24: ...
...output truncated...
Full output saved to: /home/byk/.local/share/opencode/tool-output/tool_081cf688a001iDt6OzoLdkFJGX
+ ['packages/**/cli', ['packages/cli', 'packages/nested/cli']],
+ ])('expands supported workspace glob %s', (workspaceGlob, expectedNames) => {
+ const directory = mkdtempSync(join(tmpdir(), 'craft-workspaces-'));
+ temporaryDirectories.push(directory);
+ mkdirSync(join(directory, 'packages', 'cli'), { recursive: true });
+ mkdirSync(join(directory, 'packages', 'mcp'), { recursive: true });
+ mkdirSync(join(directory, 'packages', 'api'), { recursive: true });
+ mkdirSync(join(directory, 'packages', 'nested', 'cli'), {
+ recursive: true,
+ });
+ writeFileSync(
+ join(directory, '.craft.yml'),
+ [
+ `minVersion: ${WORKSPACES_MIN_VERSION}`,
+ 'workspaces:',
+ ` "${workspaceGlob}": {}`,
+ ].join('\n'),
+ );
+ process.chdir(directory);
+
+ ...
commit f174ceafa57355e71617f32ba1b0a030953be0a2
Author: Burak Yigit Kaya <byk@sentry.io>
AuthorDate: Tue Sep 8 16:02:39 2026 +0000
Commit: Burak Yigit Kaya <byk@sentry.io>
CommitDate: Tue Sep 8 16:02:39 2026 +0000
test: describe workspace paths accurately
src/__tests__/config.test.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/__tests__/config.test.ts b/src/__tests__/config.test.ts
index 90f541a..619c940 100644
--- a/src/__tests__/config.test.ts
+++ b/src/__tests__/config.test.ts
@@ -161,7 +161,7 @@ describe('noMerge config', () => {
expect(() => validateConfiguration(data)).not.toThrow();
});
- test('allows legacy workspace names', () => {
+ test('allows multi-segment workspace paths', () => {
expect(() =>
validateConfiguration({ workspaces: { 'cli/v2': {} } }),
).not.toThrow();
<path>/home/byk/Code/getsentry/craft-workspace-action-propagation/docs/src/content/docs/targets/github.md</path>
<type>file</type>
<content>
1: ---
2: title: GitHub
3: description: Create GitHub releases and tags
4: ---
5:
6: Creates a release on GitHub. If a Markdown changelog is present, this target reads the release name and description from it.
7:
8: ## Configuration
9:
10: | Option | Description |
11: |--------|-------------|
12: | `tagPrefix` | Prefix for new git tags (e.g., `v`). Empty by default. |
13: | `previewReleases` | Automatically detect and create preview releases. Default: `true` |
14: | `tagOnly` | Only create a tag (without a GitHub release). Default: `false` |
15: | `floatingTags` | List of floating tags to create/update. Supports `{major}`, `{minor}`, `{patch}` placeholders. |
16:
17: ## Environment Variables
18:
19: | Name | Description |
20: |------|-------------|
21: | `GITHUB_TOKEN` | Personal GitHub API token ([create ...
<path>/home/byk/Code/getsentry/craft-workspace-action-propagation/.github/workflows/release.yml</path>
<type>file</type>
<content>
1: name: Release
2: concurrency: ${{ github.workflow }}-${{ github.ref }}
3:
4: on:
5: # For Craft's own releases (dogfooding)
6: workflow_dispatch:
7: inputs:
8: version:
9: description: Version to release
10: required: true
11: default: 'auto'
12: force:
13: description: Force a release even when there are release-blockers (optional)
14: required: false
15: workspace:
16: description: Named Craft release workspace to prepare and publish
17: required: false
18:
19: # For external repos to call this workflow
20: workflow_call:
21: inputs:
22: version:
23: description: Version to release (semver, bump type, or "auto")
24: type: string
25: required: false
26: force:
27: description: Force a release even when there are ...
...output truncated...
Full output saved to: /home/byk/.local/share/opencode/tool-output/tool_081d017cd0019KinsStFF7rbL2
+ tempDirectories.push(directory);
+ const binDirectory = join(directory, 'bin');
+ const craftCalls = join(directory, 'craft-calls');
+ const ghTitles = join(directory, 'gh-titles');
+ const gitCalls = join(directory, 'git-calls');
+ const output = join(directory, 'github-output');
+ mkdirSync(binDirectory);
+ writeFileSync(craftCalls, '');
+ writeFileSync(ghTitles, '');
+ writeFileSync(gitCalls, '');
+ writeFileSync(output, '');
+ writeFileSync(
+ join(binDirectory, 'craft'),
+ '#!/usr/bin/env bash\nif [[ -n "${CRAFT_WORKSPACE:-}" ]]; then\n exit 1\nfi\nprintf "%s\\n" "$*" >> "$CRAFT_CALLS"\nif [[ "$1" == "targets" ]]; then\n printf \'["github"]\'\nfi\n',
+ );
+ writeFileSync(
+ join(binDirectory, 'git'),
+ '#!/usr/bin/env bash\nprintf "%s\\n" "$*" >> "$GIT_CALLS"\n',
+ );
+ writeFileSync(
+ join(binDirectory, 'gh'),
+ ...
Found 3 matches /home/byk/Code/getsentry/craft-workspace-action-propagation/node_modules/glob/README.md: Line 176: posix shells such as bash or zsh, the shell will first Line 192: -x --posix Always resolve to posix style paths, using '/' as the Line 588: - `posix` Set to true to use `/` as the path separator in
<path>/home/byk/Code/getsentry/craft-workspace-action-propagation/node_modules/glob/README.md</path> <type>file</type> <content> 570: - `realpath` Set to true to call `fs.realpath` on all of the 571: results. In the case of an entry that cannot be resolved, the 572: entry is omitted. This incurs a slight performance penalty, of 573: course, because of the added system calls. 574: 575: - `absolute` Set to true to always receive absolute paths for 576: matched files. Set to `false` to always receive relative paths 577: for matched files. 578: 579: By default, when this option is not set, absolute paths are 580: returned for patterns that are absolute, and otherwise paths 581: are returned that are relative to the `cwd` setting. 582: 583: This does _not_ make an extra system call to get the realpath, 584: it only does string path resolution. 585: 586: `absolute` may not be used along with `withFileTypes`. ...
<path>/home/byk/Code/getsentry/craft-workspace-action-propagation/package.json</path>
<type>file</type>
<content>
1: {
2: "name": "@sentry/craft",
3: "version": "2.31.0-dev.0",
4: "description": "The universal sentry workflow CLI",
5: "main": "dist/craft",
6: "repository": "https://github.com/getsentry/craft",
7: "author": "Sentry",
8: "license": "MIT",
9: "bin": {
10: "craft": "dist/craft",
11: "sentry-craft": "dist/craft"
12: },
13: "devDependencies": {
14: "@aws-sdk/client-lambda": "^3.984.0",
15: "@eslint/js": "^9.17.0",
16: "@google-cloud/storage": "^7.14.0",
17: "@octokit/plugin-retry": "^7.1.2",
18: "@octokit/request-error": "^7.0.0",
19: "@octokit/rest": "^21.0.2",
20: "@sentry/esbuild-plugin": "^2.23.0",
21: "@sentry/node": "^10.27.0",
22: "@types/async": "^3.0.1",
23: "@types/aws4": "^1.5.1",
24: "@types/cli-table": "^0.3.0",
25: "@types/git-url-parse": "^9.0.0",
26: "@types/is-ci": "^2.0.0",
27: ...
<path>/home/byk/Code/getsentry/craft-workspace-action-propagation/tsconfig.json</path>
<type>file</type>
<content>
1: {
2: "extends": "./tsconfig.build.json",
3: "compilerOptions": {
4: "types": ["node", "vitest/globals"],
5: "plugins": [],
6: "incremental": true,
7: "tsBuildInfoFile": ".tsbuildinfo"
8: },
9: "include": ["src/**/*.ts", "**/__mocks__/**/*.ts", "**/__tests_/**/*.ts"],
10: "exclude": ["dist/**/*"]
11: }
(End of file - total 11 lines)
</content>
(no output)
Checking formatting... All matched files use Prettier code style!
vitest/4.1.8 Usage: $ vitest [...filters] Commands: run [...filters] related [...filters] watch [...filters] dev [...filters] bench [...filters] init <project> list [...filters] [...filters] complete [shell] For more info, run any command with the `--help` flag: $ vitest run --help $ vitest related --help $ vitest watch --help $ vitest dev --help $ vitest bench --help $ vitest init --help $ vitest list --help $ vitest --help $ vitest complete --help $ vitest --help --expand-help Options: -v, --version Display version number -r, --root <path> Root path -c, --config <path> Path to config file -u, --update [type] Update snapshot (accepts boolean, "new", "all" or "none") -w, --watch ...
RUN v4.1.8 /home/byk/Code/getsentry/craft-workspace-action-propagation
Test Files 5 passed (5)
Tests 141 passed (141)
Start at 16:24:25
Duration 21.98s (transform 2.74s, setup 0ms, import 10.66s, tests 8.09s, environment 1ms)
/home/byk/Code/getsentry/craft-workspace-action-propagation/src/commands/publish.ts 482:14 warning '_abortError' is defined but never used @typescript-eslint/no-unused-vars 499:14 warning '_abortError' is defined but never used @typescript-eslint/no-unused-vars 515:16 warning '_statusError' is defined but never used @typescript-eslint/no-unused-vars 521:18 warning '_diffError' is defined but never used @typescript-eslint/no-unused-vars 527:16 warning '_abortError' is defined but never used @typescript-eslint/no-unused-vars ✖ 5 problems (0 errors, 5 warnings)
453: 453 } catch (_abortError) {
470: 470 } catch (_abortError) {
486: 486 } catch (_statusError) {
492: 492 } catch (_diffError) {
498: 498 } catch (_abortError) {
5:@@ -18,7 +18,10 @@ import {
17:@@ -166,6 +169,32 @@ export interface PublishState {
50:@@ -602,9 +631,7 @@ export async function publishMain(argv: PublishOptions): Promise<any> {
61:@@ -696,7 +723,7 @@ export async function publishMain(argv: PublishOptions): Promise<any> {
70:@@ -903,6 +930,20 @@ export async function publishMain(argv: PublishOptions): Promise<any> {
Found 20 matches
/home/byk/Code/getsentry/craft-workspace-action-propagation/action.yml:
Line 34: workspace:
Line 35: description: Named Craft release workspace to prepare and publish
Line 74: - name: Validate workspace
Line 79: WORKSPACE: ${{ inputs.workspace }}
Line 82: echo "::error::The path and workspace inputs cannot be used together."
Line 89: if [[ -n "$WORKSPACE" ]] && ! node -e 'const workspace = process.env.WORKSPACE; const segment = /^[A-Za-z0-9_.-]+$/; process.exit(workspace.split("/").every(name => segment.test(name) && ![".", "..", "__proto__"].includes(name) && !name.startsWith("-")) ? 0 : 1)'; then
Line 188: WORKSPACE: ${{ inputs.workspace }}
Line 201: CRAFT_ARGS+=("--workspace=$WORKSPACE")
Line 218: WORKSPACE: ${{ inputs.workspace }}
Line 223: CRAFT_ARGS=("--workspace=$WORKSPACE")
Line 248: WORKSPACE: ${{ inputs.workspace ...
<path>/home/byk/Code/getsentry/craft-workspace-action-propagation/src/utils/__tests__/helpers.test.ts</path>
<type>file</type>
<content>
1: import { existsSync, mkdirSync, readFileSync, rmSync } from 'fs';
2: import path from 'path';
3: import { tmpdir } from 'os';
4:
5: import { afterEach, beforeEach, describe, expect, test } from 'vitest';
6:
7: import {
8: disableChangelogMentions,
9: envToBool,
10: extractWorkspaceSelection,
11: MAX_STEP_OUTPUT_BYTES,
12: setGitHubActionsOutput,
13: truncateForOutput,
14: writeGitHubActionsFile,
15: } from '../helpers';
16:
17: describe('envToBool', () =>
18: test.each([
19: [undefined, false],
20: [null, false],
21: [false, false],
22: ['undefined', false],
23: ['null', false],
24: ['', false],
25: ['0', false],
26: ['no', false],
27: [true, true],
28: ['true', true],
29: [1, true],
30: ['1', true],
31: ['yes', true],
32: ['dogs are great!', true],
33: ])('From %j we ...
RUN v4.1.8 /home/byk/Code/getsentry/craft-workspace-action-propagation [info] [[target/github]] No previous release found [info] [[target/github]] Deleted orphaned draft release: v1.0.0 [info] [[target/github]] No previous release found [warn] [[target/github]] Failed to clean up release "v1.0.0": Error: Cleanup failed [info] [[target/github]] No previous release found [info] [[target/github]] No previous release found [info] [[target/github]] Release for tag "1.0.0" already exists and is published. Skipping GitHub release creation (likely from a previous run). [info] [[target/github]] No previous release found [info] [[target/github]] createRelease returned 422 for tag "1.0.0". Looking for a leftover draft release to clean up... [info] [[target/github]] Deleting leftover draft release (id=789) for tag "1.0.0"... [info] [[target/github]] No previous release found [warn] [[target/github]] Release "v1.0.0" was already published on GitHub despite the error. ...
PASS — no MUST-FIX or CONCERN findings.
f174ceafa57355e71617f32ba1b0a030953be0a2 against origin/master (21270a1d12a60b461c51fba93bd076b90d9cf4af), which is also the merge-base. Working tree remained clean; all 16 changed files were inspected; git diff --check passed.src/schemas/project_config.ts:322-334), glob results use POSIX separators (src/config.ts:243-262), matching uses exact strings (src/config.ts:191-199), action titles retain the complete path (action.yml:275), and state names encode the unmodified workspace identity (src/utils/publishState.ts:95-105).__proto__, option-like segments, empty segments, backslashes, non-ASCII/control values, and unsafe glob syntax fail closed in schema/runtime/action validation (src/schemas/project_config.ts:219-334, src/config.ts:231-327, action.yml:74-92).src/config.ts:235-262). Brace parsing rejects malformed or unsafe alternatives (src/config.ts:330-390).src/commands/prepare.ts:806-812); string configuration accepts that explicit root (src/config.ts:597-606).CRAFT_WORKSPACE is cleared; workspace commands receive an inline argument; titles include the full workspace path (action.yml:74-92, 191-224, 275). ...Date: Sep 8, 2026 * 🟡 (16:46) Full Vitest run in `/home/byk/Code/getsentry/craft-workspace-action-propagation` completed successfully: 61 test files passed; 1,197 tests passed, 1 skipped (1,198 total); duration 70.86s (transform 2.02s, import 35.92s, tests 22.91s). Test output included expected target/GitHub release cleanup and truncation logs. * 🟡 (16:46) Full Vitest emitted two Vite/esbuild S…
Date: Sep 8, 2026 * 🟡 (16:39) Repository search found 20 `workspace` matches in `/home/byk/Code/getsentry/craft-workspace-action-propagation`: `action.yml` defines input `workspace` at lines 34–35 (“Named Craft release workspace to prepare and publish”), validates it around lines 74–89, rejects simultaneous `path` and `workspace` inputs at line 82, validates slash-separated segments with `/^[A-Z…
Date: Sep 8, 2026 * 🟡 (16:32) Vitest `v4.1.8` ran in `/home/byk/Code/getsentry/craft-workspace-action-propagation`: 5 test files passed; 141 tests passed; duration 21.98s (transform 2.74s, setup 0ms, import 10.66s, tests 8.09s, environment 1ms). * 🔴 (16:36) User stated `@typescript-eslint/no-unused-vars` warnings reported `_abortError` as defined but never used at `src/commands/publish.ts:482:1…
Date: Sep 8, 2026 * 🔴 (16:25) User preference/directive: always print console stack traces. * 🟡 (16:25) Vitest CLI version is `vitest/4.1.8`; its help documents `--printConsoleTrace` as the option to always print console stack traces.
Date: Sep 8, 2026 * 🔴 (16:16) User stated that when no pre-release command runs, `commitChanges()` commits only explicitly staged files such as the changelog, so stray working-tree changes are never swept in by accident. * 🔴 (16:16) User stated that `execPublish()` will never return: it terminates the process with the corresponding error code after publishing is done. * 🔴 (16:16) User stated r…
Date: Sep 8, 2026 * 🔴 (16:18) User stated that Glob’s `posix: true` option always resolves returned paths to POSIX style, using `/` separators. * 🔴 (16:18) User stated that Glob’s `absolute: true` option always receives absolute paths for matched files. * 🔴 (16:18) User stated that Glob’s `absolute: false` option always receives relative paths for matched files. * 🟡 (16:18) `.github/workflows…
Date: Sep 8, 2026 * 🔴 (16:17) User stated that floating tags always point to the most recent release. * 🔴 (16:17) User stated that Action publish titles always carry the full concrete workspace path. * 🟡 (16:17) Commit `f174ceafa57355e71617f32ba1b0a030953be0a2` (`test: describe workspace paths accurately`, authored/committed Sep 8, 2026 16:02:39 UTC) renamed the `src/__tests__/config.test.ts` …
Date: Sep 8, 2026 * 🟡 (16:17) `src/commands/workspace_cmds/__tests__/list.test.ts` tests the `workspace list` command. It mocks `getWorkspaceNames` from `../../../config` and `formatJson` from `../../../utils/strings` as `JSON.stringify(value)`. * 🟡 (16:17) `workspace list command` test `prints exact configured workspace names` configures `getWorkspaceNames()` to return `['cli', 'mcp.v2']`, inv…
Date: Sep 8, 2026 * 🟡 (16:16) `src/__tests__/action.test.ts` provides GitHub Action integration-style tests using temporary directories (`craft-action-test-`), stub executables for `craft`, `git`, and `gh`, and `spawnSync('bash', ['-e', '-c', getActionStep(stepName).run!])`; `afterEach()` removes all temporary directories recursively. * 🟡 (16:16) Action test stub behavior: `craft` exits with st…
Date: Sep 8, 2026 * 🟡 (16:15) `src/commands/workspace_cmds/list.ts` defines the `workspace list` subcommand: `command = ['list']`, description `'List defined release workspaces as a JSON array'`, and `handler()` outputs `formatJson(getWorkspaceNames())` with `console.log`. * 🟡 (16:15) `src/index.ts` imports `workspace` from `./commands/workspace`, registers it through `.command(workspace)`, and…
Date: Sep 8, 2026 * 🟡 (16:15) Repository branch `feat/workspace-action-propagation` HEAD is commit `f174cea` / `f174ceafa57355e71617f32ba1b0a030953be0a2`, with recent commits: `f174cea` “test: describe workspace paths accurately”; `d48b906` “feat: support concrete release workspaces”; `4862056` “feat: support compact release workspaces”; and `6dae341` “feat: propagate release workspaces”. * 🟡 (…
Date: Sep 8, 2026 * 🟡 (16:14) Exact-head/diff-hygiene tool output reported PR head `f174ceafa57355e71617f32ba1b0a030953be0a2` and comparison/base commit `21270a1d12a60b461c51fba93bd076b90d9cf4af` (reported twice). * 🟡 (16:14) Tool output listed 15 changed paths: modified `.github/workflows/release.yml`, `action.yml`, `docs/src/content/docs/targets/github.md`, `src/__tests__/config.test.ts`, `sr…
Date: Sep 8, 2026 * 🟡 [requested-code-review] (16:14) User requested a strict, read-only adversarial review of Craft PR #872 at exact head `f174ceafa57355e71617f32ba1b0a030953be0a2` in `/home/byk/Code/getsentry/craft-workspace-action-propagation`, compared against `origin/master`. * 🔴 [enforced-read-only] (16:14) User required that the PR review not edit, format, commit, or otherwise mutate fil…