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
10 changes: 10 additions & 0 deletions .agents/skills/pgpm/references/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,16 @@ Non-interactive init requires every question to be answered by flags; see
`--name --fullName --email --username --repoName --license`, plus module
`--moduleName --packageIdentifier --moduleDesc --access`.

When a module is created, `pgpm init` also adds its workspace-relative path to
each `jobs.<job>.strategy.matrix.package` list in the workspace's
`.github/workflows/*.yml` (sorted, in place). The workflow is parsed with `yaml`
to address that path, and only the matrix list's own byte range is rewritten, so
comments and formatting survive where they can be preserved. A matrix whose
comments cannot be preserved is left untouched. The list stays a plain YAML
array you can hand-edit; workflows without such a matrix — or whose matrix isn't
a plain list of strings — or that can't be read or written — are left alone
silently; the update is best-effort and never warns.

### Workspace Inspection

**pgpm ls** — List the pgpm modules in the current workspace
Expand Down
68 changes: 67 additions & 1 deletion pgpm/cli/__tests__/init.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ process.env.PGPM_SKIP_UPDATE_CHECK = 'true';
process.env.PGPM_SKIP_SKILL_INSTALL = 'true';

import { PgpmPackage, TEMPLATE_REPOS } from '@pgpmjs/core';
import { existsSync, mkdirSync, readFileSync } from 'fs';
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
import { sync as glob } from 'glob';
import { Inquirerer, ParsedArgs } from 'inquirerer';
import * as path from 'path';
Expand Down Expand Up @@ -538,6 +538,72 @@ describe('cmds:init', () => {
expect(existsSync(path.join(modDir, 'pgpm.plan'))).toBe(true);
expect(existsSync(path.join(modDir, 'package.json'))).toBe(true);
});

it('adds each new module to the CI matrix, sorted', async () => {
const { mockInput, mockOutput } = environment;
const prompter = new Inquirerer({
input: mockInput,
output: mockOutput,
noTty: true
});

const wsName = 'ws-ci-matrix';
const wsRoot = path.join(fixture.tempDir, wsName);

await commands(withInitDefaults({
_: ['init', 'workspace'],
cwd: fixture.tempDir,
name: wsName,
workspace: true
}), prompter, {
noTty: true,
input: mockInput,
output: mockOutput,
version: '1.0.0',
minimistOpts: {}
});

const workflow = path.join(wsRoot, '.github', 'workflows', 'ci.yml');
mkdirSync(path.dirname(workflow), { recursive: true });
writeFileSync(workflow, [
'jobs:',
' test:',
' strategy:',
' matrix:',
' # kept sorted by pgpm init',
' package: []',
' steps:',
' - run: cd ./${{ matrix.package }} && pnpm test',
''
].join('\n'));

for (const modName of ['zeta', 'alpha']) {
await commands(withInitDefaults({
_: ['init'],
cwd: wsRoot,
moduleName: modName,
name: modName
}), prompter, {
noTty: true,
input: mockInput,
output: mockOutput,
version: '1.0.0',
minimistOpts: {}
});
}

expect(readFileSync(workflow, 'utf8')).toBe([
'jobs:',
' test:',
' strategy:',
' matrix:',
' # kept sorted by pgpm init',
' package: [packages/alpha, packages/zeta]',
' steps:',
' - run: cd ./${{ matrix.package }} && pnpm test',
''
].join('\n'));
});
});

describe('--create-workspace flag', () => {
Expand Down
11 changes: 11 additions & 0 deletions pgpm/cli/src/commands/init/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
addToCiMatrix,
BoilerplateSkill,
DEFAULT_TEMPLATE_REPO,
DEFAULT_TEMPLATE_TOOL_NAME,
Expand Down Expand Up @@ -866,6 +867,16 @@ async function handleModuleInit(
});
}

if (resolvedWorkspacePath) {
const matrixFiles = addToCiMatrix(
resolvedWorkspacePath,
path.relative(resolvedWorkspacePath, modulePath)
);
for (const file of matrixFiles) {
process.stdout.write(`Added ${modName} to the CI matrix in ${file}\n`);
}
}

const motdPath = path.join(modulePath, '.motd');
let motd = DEFAULT_MOTD;
if (fs.existsSync(motdPath)) {
Expand Down
Loading
Loading