Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -41921,7 +41921,7 @@ async function run() {
// Install extra inline deps additively
if (depsInput) {
const deps = parseDependencies(depsInput);
await installDeps(resolvedDir, deps);
await installDeps(resolvedDir, deps, validatedTarget);
}
}
// Run content audit if report requested
Expand Down Expand Up @@ -42064,23 +42064,29 @@ function parseDependencies(input) {
}
/**
* Install dependencies additively via `apm install <dep>`.
*
* If `target` is provided it is forwarded as `--target <target>` so APM
* v0.12.3+ strict harness detection has an explicit signal. Without it,
* additive installs into a workspace with no harness markers
* (`.github/copilot-instructions.md`, `.claude/`, `CLAUDE.md`, etc.) exit
* with code 2.
*/
async function installDeps(dir, deps) {
async function installDeps(dir, deps, target) {
lib_core/* info */.pq(`Installing ${deps.length} inline dependencies...`);
const targetArgs = target ? ['--target', target] : [];
for (const dep of deps) {
if (typeof dep === 'string') {
await runApm(['install', dep], dir);
await runApm(['install', dep, ...targetArgs], dir);
}
else {
// Object-form: build the install argument
let installArg = dep.git;
if (dep.path) {
installArg += `#path=${dep.path}`;
}
if (dep.ref) {
installArg += (installArg.includes('#') ? '&' : '#') + `ref=${dep.ref}`;
}
await runApm(['install', installArg], dir);
await runApm(['install', installArg, ...targetArgs], dir);
}
}
}
Expand Down
33 changes: 33 additions & 0 deletions src/__tests__/runner.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,39 @@ describe('run', () => {
expect(mockSetFailed).not.toHaveBeenCalled();
});

it('forwards --target to additive apm install (non-isolated mode)', async () => {
// Regression: APM v0.12.3+ rejects `apm install <pkg>` with exit 2
// ("No harness detected") when the workspace has no harness markers.
// The non-isolated additive path (apm.yml absent, inline deps present)
// must forward the action's `target` input as `--target <value>` on
// every per-dep install call, mirroring what isolated mode does via
// the generated apm.yml.
const installCalls: string[][] = [];
mockExec.mockImplementation((cmd: string, args?: string[]) => {
if (cmd === 'apm' && args?.[0] === 'install') installCalls.push(args);
return Promise.resolve(0);
});

mockGetInput.mockImplementation((name: unknown) => {
switch (name) {
case 'working-directory': return tmpDir;
case 'dependencies': return 'microsoft/apm-sample-package';
case 'isolated': return 'false';
case 'target': return 'copilot';
case 'pack': return 'false';
case 'compile': return 'false';
default: return '';
}
});

await run();

expect(mockSetFailed).not.toHaveBeenCalled();
expect(installCalls).toEqual([
['install', 'microsoft/apm-sample-package', '--target', 'copilot'],
]);
});

it('fails fast when working directory does not exist in non-isolated mode', async () => {
const nonExistentDir = path.join(tmpDir, 'does-not-exist');

Expand Down
16 changes: 11 additions & 5 deletions src/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ export async function run(): Promise<void> {
// Install extra inline deps additively
if (depsInput) {
const deps = parseDependencies(depsInput);
await installDeps(resolvedDir, deps);
await installDeps(resolvedDir, deps, validatedTarget);
}
Comment on lines 323 to 327
}

Expand Down Expand Up @@ -490,22 +490,28 @@ function parseDependencies(input: string): Dependency[] {

/**
* Install dependencies additively via `apm install <dep>`.
*
* If `target` is provided it is forwarded as `--target <target>` so APM
* v0.12.3+ strict harness detection has an explicit signal. Without it,
* additive installs into a workspace with no harness markers
* (`.github/copilot-instructions.md`, `.claude/`, `CLAUDE.md`, etc.) exit
* with code 2.
*/
async function installDeps(dir: string, deps: Dependency[]): Promise<void> {
async function installDeps(dir: string, deps: Dependency[], target?: string): Promise<void> {
core.info(`Installing ${deps.length} inline dependencies...`);
const targetArgs = target ? ['--target', target] : [];
for (const dep of deps) {
if (typeof dep === 'string') {
await runApm(['install', dep], dir);
await runApm(['install', dep, ...targetArgs], dir);
} else {
// Object-form: build the install argument
let installArg = dep.git;
if (dep.path) {
installArg += `#path=${dep.path}`;
}
if (dep.ref) {
installArg += (installArg.includes('#') ? '&' : '#') + `ref=${dep.ref}`;
}
await runApm(['install', installArg], dir);
await runApm(['install', installArg, ...targetArgs], dir);
}
}
}
Expand Down
Loading