diff --git a/API.md b/API.md index b7b1a1a2..e8606631 100644 --- a/API.md +++ b/API.md @@ -4378,6 +4378,173 @@ public readonly DEFAULT_TS_JEST_TRANFORM_PATTERN: string; --- +### Triage + +Add a Triage workflow to our repos. + +> [https://github.com/marketplace/actions/add-to-github-projects](https://github.com/marketplace/actions/add-to-github-projects) + +#### Initializers + +```typescript +import { Triage } from '@cdk8s/projen-common' + +new Triage(project: NodeProject, props: TriageProps) +``` + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| project | projen.javascript.NodeProject | *No description.* | +| props | TriageProps | *No description.* | + +--- + +##### `project`Required + +- *Type:* projen.javascript.NodeProject + +--- + +##### `props`Required + +- *Type:* TriageProps + +--- + +#### Methods + +| **Name** | **Description** | +| --- | --- | +| toString | Returns a string representation of this construct. | +| postSynthesize | Called after synthesis. | +| preSynthesize | Called before synthesis. | +| synthesize | Synthesizes files to the project output directory. | + +--- + +##### `toString` + +```typescript +public toString(): string +``` + +Returns a string representation of this construct. + +##### `postSynthesize` + +```typescript +public postSynthesize(): void +``` + +Called after synthesis. + +Order is *not* guaranteed. + +##### `preSynthesize` + +```typescript +public preSynthesize(): void +``` + +Called before synthesis. + +##### `synthesize` + +```typescript +public synthesize(): void +``` + +Synthesizes files to the project output directory. + +#### Static Functions + +| **Name** | **Description** | +| --- | --- | +| isConstruct | Checks if `x` is a construct. | +| isComponent | Test whether the given construct is a component. | + +--- + +##### `isConstruct` + +```typescript +import { Triage } from '@cdk8s/projen-common' + +Triage.isConstruct(x: any) +``` + +Checks if `x` is a construct. + +Use this method instead of `instanceof` to properly detect `Construct` +instances, even when the construct library is symlinked. + +Explanation: in JavaScript, multiple copies of the `constructs` library on +disk are seen as independent, completely different libraries. As a +consequence, the class `Construct` in each copy of the `constructs` library +is seen as a different class, and an instance of one class will not test as +`instanceof` the other class. `npm install` will not create installations +like this, but users may manually symlink construct libraries together or +use a monorepo tool: in those cases, multiple copies of the `constructs` +library can be accidentally installed, and `instanceof` will behave +unpredictably. It is safest to avoid using `instanceof`, and using +this type-testing method instead. + +###### `x`Required + +- *Type:* any + +Any object. + +--- + +##### `isComponent` + +```typescript +import { Triage } from '@cdk8s/projen-common' + +Triage.isComponent(x: any) +``` + +Test whether the given construct is a component. + +###### `x`Required + +- *Type:* any + +--- + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| node | constructs.Node | The tree node. | +| project | projen.Project | *No description.* | + +--- + +##### `node`Required + +```typescript +public readonly node: Node; +``` + +- *Type:* constructs.Node + +The tree node. + +--- + +##### `project`Required + +```typescript +public readonly project: Project; +``` + +- *Type:* projen.Project + +--- + + ## Structs ### Cdk8sTeamJsiiProjectOptions @@ -4551,6 +4718,7 @@ const cdk8sTeamJsiiProjectOptions: Cdk8sTeamJsiiProjectOptions = { ... } | backport | boolean | Configure a backport workflow. | | backportBranches | string[] | Branches to backport to. | | repoName | string | The name of the repository inside the cdk8s-team org where the code of the project is locate in. | +| triageOptions | TriageOptions | Options for the `triage` workflow. | | golang | boolean | Publish Golang bindings to GitHub. | | golangBranch | string | Name of the branch in the golang repository to publish to. | | jsiiVersion | string | JSII version to use. | @@ -6671,6 +6839,19 @@ The name of the repository inside the cdk8s-team org where the code of the proje --- +##### `triageOptions`Optional + +```typescript +public readonly triageOptions: TriageOptions; +``` + +- *Type:* TriageOptions +- *Default:* no custom options. + +Options for the `triage` workflow. + +--- + ##### `golang`Optional ```typescript @@ -6895,6 +7076,7 @@ const cdk8sTeamNodeProjectOptions: Cdk8sTeamNodeProjectOptions = { ... } | backport | boolean | Configure a backport workflow. | | backportBranches | string[] | Branches to backport to. | | repoName | string | The name of the repository inside the cdk8s-team org where the code of the project is locate in. | +| triageOptions | TriageOptions | Options for the `triage` workflow. | --- @@ -8754,6 +8936,19 @@ The name of the repository inside the cdk8s-team org where the code of the proje --- +##### `triageOptions`Optional + +```typescript +public readonly triageOptions: TriageOptions; +``` + +- *Type:* TriageOptions +- *Default:* no custom options. + +Options for the `triage` workflow. + +--- + ### Cdk8sTeamTypeScriptProjectOptions Options for `Cdk8sTeamTypeScriptProject`. @@ -8919,6 +9114,7 @@ const cdk8sTeamTypeScriptProjectOptions: Cdk8sTeamTypeScriptProjectOptions = { . | backport | boolean | Configure a backport workflow. | | backportBranches | string[] | Branches to backport to. | | repoName | string | The name of the repository inside the cdk8s-team org where the code of the project is locate in. | +| triageOptions | TriageOptions | Options for the `triage` workflow. | --- @@ -11033,5 +11229,153 @@ The name of the repository inside the cdk8s-team org where the code of the proje --- +##### `triageOptions`Optional + +```typescript +public readonly triageOptions: TriageOptions; +``` + +- *Type:* TriageOptions +- *Default:* no custom options. + +Options for the `triage` workflow. + +--- + +### CommonComponentsOptions + +Options for `addComponents`. + +#### Initializer + +```typescript +import { CommonComponentsOptions } from '@cdk8s/projen-common' + +const commonComponentsOptions: CommonComponentsOptions = { ... } +``` + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| branches | string[] | *No description.* | +| compilerDeps | string[] | *No description.* | +| triageOptions | TriageOptions | *No description.* | + +--- + +##### `branches`Optional + +```typescript +public readonly branches: string[]; +``` + +- *Type:* string[] + +--- + +##### `compilerDeps`Optional + +```typescript +public readonly compilerDeps: string[]; +``` + +- *Type:* string[] + +--- + +##### `triageOptions`Optional + +```typescript +public readonly triageOptions: TriageOptions; +``` + +- *Type:* TriageOptions + +--- + +### TriageOptions + +Options for `Triage`. + +#### Initializer + +```typescript +import { TriageOptions } from '@cdk8s/projen-common' + +const triageOptions: TriageOptions = { ... } +``` + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| prLabels | string[] | A list of labels automatically added to PRs. | + +--- + +##### `prLabels`Optional + +```typescript +public readonly prLabels: string[]; +``` + +- *Type:* string[] +- *Default:* no labels. + +A list of labels automatically added to PRs. + +Automation PRs are excluded. + +--- + +### TriageProps + +Props for `Triage`. + +#### Initializer + +```typescript +import { TriageProps } from '@cdk8s/projen-common' + +const triageProps: TriageProps = { ... } +``` + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| prLabels | string[] | A list of labels automatically added to PRs. | +| repoName | string | The repository name. | + +--- + +##### `prLabels`Optional + +```typescript +public readonly prLabels: string[]; +``` + +- *Type:* string[] +- *Default:* no labels. + +A list of labels automatically added to PRs. + +Automation PRs are excluded. + +--- + +##### `repoName`Required + +```typescript +public readonly repoName: string; +``` + +- *Type:* string + +The repository name. + +--- + diff --git a/src/components/index.ts b/src/components/index.ts new file mode 100644 index 00000000..aa105dde --- /dev/null +++ b/src/components/index.ts @@ -0,0 +1 @@ +export * from './triage/triage'; \ No newline at end of file diff --git a/src/components/triage/triage.ts b/src/components/triage/triage.ts index d89eec45..a1dd7d9a 100644 --- a/src/components/triage/triage.ts +++ b/src/components/triage/triage.ts @@ -3,9 +3,9 @@ import { JobPermission } from 'projen/lib/github/workflows-model'; import { NodeProject } from 'projen/lib/javascript'; /** - * Options for `Triage`. + * Props for `Triage`. */ -export interface TriageOptions { +export interface TriageProps extends TriageOptions { /** * The repository name. @@ -14,6 +14,22 @@ export interface TriageOptions { } +/** + * Options for `Triage`. + */ +export interface TriageOptions { + + + /** + * A list of labels automatically added to PRs. + * Automation PRs are excluded. + * + * @default - no labels. + */ + readonly prLabels?: string[]; + +} + /** * Add a Triage workflow to our repos. * @@ -21,7 +37,7 @@ export interface TriageOptions { */ export class Triage extends Component { - constructor(project: NodeProject, options: TriageOptions) { + constructor(project: NodeProject, props: TriageProps) { super(project); // hmm, we need to remember to update this in 2024 @@ -39,10 +55,10 @@ export class Triage extends Component { }); workflow.addJob('assign-to-project', { permissions: { issues: JobPermission.WRITE, pullRequests: JobPermission.WRITE }, - // dont dont triage issues/prs on forks + // dont triage issues/prs on forks // dont triage autimation bot prs // see https://docs.github.com/en/actions/using-jobs/using-conditions-to-control-job-execution#example-only-run-job-for-specific-repository - if: `(github.repository == \'cdk8s-team/${options.repoName}\') && (github.event.issue || (github.event.pull_request.user.login != \'cdk8s-automation\' && github.event.pull_request.head.repo.full_name == github.repository))`, + if: `(github.repository == \'cdk8s-team/${props.repoName}\') && (github.event.issue || (github.event.pull_request.user.login != \'cdk8s-automation\' && github.event.pull_request.head.repo.full_name == github.repository))`, runsOn: ['ubuntu-latest'], steps: [{ uses: 'actions/add-to-project@v0.4.0', @@ -53,5 +69,21 @@ export class Triage extends Component { }], }); + if (props.prLabels) { + workflow.addJob('add-labels-to-pr', { + permissions: { pullRequests: JobPermission.WRITE }, + if: `(github.repository == \'cdk8s-team/${props.repoName}\') && (github.event.pull_request && github.event.pull_request.user.login != \'cdk8s-automation\')`, + runsOn: ['ubuntu-latest'], + steps: [{ + uses: 'actions-ecosystem/action-add-labels@v1', + with: { + // weird: https://github.com/actions-ecosystem/action-add-labels/blob/main/src/main.ts#L10 + labels: props.prLabels.join('\n'), + github_token: '${{ secrets.PROJEN_GITHUB_TOKEN }}', + }, + }], + }); + } + } } \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 9dc7d874..27995b67 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1 +1,2 @@ -export * from './projects'; \ No newline at end of file +export * from './projects'; +export * from './components'; \ No newline at end of file diff --git a/src/projects/jsii.ts b/src/projects/jsii.ts index 31733de6..76b80596 100644 --- a/src/projects/jsii.ts +++ b/src/projects/jsii.ts @@ -102,7 +102,11 @@ export class Cdk8sTeamJsiiProject extends cdk.JsiiProject { 'jsii-rosetta', 'typescript']; - node.addComponents(this, repoName, finalOptions.depsUpgradeOptions?.workflowOptions?.branches, compilerDependencies); + node.addComponents(this, repoName, { + branches: finalOptions.depsUpgradeOptions?.workflowOptions?.branches, + compilerDeps: compilerDependencies, + triageOptions: options.triageOptions, + }); if (options.backport ?? false) { new Backport(this, { branches: options.backportBranches, repoName }); diff --git a/src/projects/node.ts b/src/projects/node.ts index 03ce61b4..85812b1a 100644 --- a/src/projects/node.ts +++ b/src/projects/node.ts @@ -8,7 +8,7 @@ import { GitHooks } from '../components/git-hooks/git-hooks'; import { IssueTemplates } from '../components/issue-templates/issue-templates'; import { Security } from '../components/security/security'; import { Stale } from '../components/stale/stale'; -import { Triage } from '../components/triage/triage'; +import { Triage, TriageOptions } from '../components/triage/triage'; export const NAME_PREFIX = 'cdk8s-'; export const SCOPE = '@cdk8s/'; @@ -145,6 +145,14 @@ export interface Cdk8sTeamNodeProjectOptions extends javascript.NodeProjectOptio * @default - Will be derived from PR labels. */ readonly backportBranches?: string[]; + + /** + * Options for the `triage` workflow. + * + * @default - no custom options. + */ + readonly triageOptions?: TriageOptions; + } /** @@ -169,7 +177,10 @@ export class Cdk8sTeamNodeProject extends javascript.NodeProject { const repoName = options.repoName ?? buildRepositoryName(options.name); - addComponents(this, repoName, finalOptions.depsUpgradeOptions?.workflowOptions?.branches); + addComponents(this, repoName, { + branches: finalOptions.depsUpgradeOptions?.workflowOptions?.branches, + triageOptions: options.triageOptions, + }); if (options.backport ?? false) { new Backport(this, { branches: options.backportBranches, repoName }); @@ -225,17 +236,26 @@ export function validateProjectName(options: Cdk8sTeamNodeProjectOptions) { } +/** + * Options for `addComponents`. + */ +export interface CommonComponentsOptions { + readonly branches?: string[]; + readonly compilerDeps?: string[]; + readonly triageOptions?: TriageOptions; +} + /** * Add common components to the project. */ -export function addComponents(project: NodeProject, repoName: string, branches?: string[], compilerDeps?: string[]) { +export function addComponents(project: NodeProject, repoName: string, options: CommonComponentsOptions) { new CodeOfConductMD(project); new DCO(project); new GitHooks(project); new IssueTemplates(project, { repoName }); new Security(project); - new Triage(project, { repoName }); + new Triage(project, { repoName, ...options.triageOptions }); new Stale(project); const configDeps = ['projen']; @@ -249,31 +269,31 @@ export function addComponents(project: NodeProject, repoName: string, branches?: pullRequestTitle: 'upgrade configuration', types: [DependencyType.BUILD], workflowOptions: { - branches, + branches: options.branches, labels: ['auto-approve'], schedule: UpgradeDependenciesSchedule.expressions([UPGRADE_CONFIGURATION_SCHEDULE]), }, }); new UpgradeDependencies(project, { - exclude: [...configDeps, ...(compilerDeps ?? [])], + exclude: [...configDeps, ...(options.compilerDeps ?? [])], taskName: 'upgrade-dev-dependencies', pullRequestTitle: 'upgrade dev dependencies', workflowOptions: { - branches, + branches: options.branches, labels: ['auto-approve'], schedule: UpgradeDependenciesSchedule.expressions([UPGRADE_DEV_DEPENDENCIES_SCHEDULE]), }, types: [DependencyType.BUILD, DependencyType.BUNDLED, DependencyType.DEVENV, DependencyType.TEST], }); - if (compilerDeps && compilerDeps.length > 0) { + if (options.compilerDeps && options.compilerDeps.length > 0) { new UpgradeDependencies(project, { - include: compilerDeps, + include: options.compilerDeps, taskName: 'upgrade-compiler-dependencies', pullRequestTitle: 'upgrade compiler dependencies', workflowOptions: { - branches, + branches: options.branches, labels: ['auto-approve'], schedule: UpgradeDependenciesSchedule.expressions([UPGRADE_COMPILER_DEPENDENCIES_SCHEDULE]), }, diff --git a/src/projects/typescript.ts b/src/projects/typescript.ts index 60bf36cf..22789680 100644 --- a/src/projects/typescript.ts +++ b/src/projects/typescript.ts @@ -1,6 +1,7 @@ import * as deepmerge from 'deepmerge'; import { DependencyType, typescript } from 'projen'; import * as node from './node'; +import { TriageOptions } from '../components'; import { Backport } from '../components/backport/backport'; /** @@ -36,6 +37,14 @@ export interface Cdk8sTeamTypeScriptProjectOptions extends typescript.TypeScript * @default - No additional compiler dependencies. */ readonly additionalCompilerDependencies?: string[]; + + /** + * Options for the `triage` workflow. + * + * @default - no custom options. + */ + readonly triageOptions?: TriageOptions; + } /** @@ -61,7 +70,11 @@ export class Cdk8sTeamTypeScriptProject extends typescript.TypeScriptProject { const compilerDependencies = [...(options.additionalCompilerDependencies ?? []), 'typescript']; - node.addComponents(this, repoName, finalOptions.depsUpgradeOptions?.workflowOptions?.branches, compilerDependencies); + node.addComponents(this, repoName, { + branches: finalOptions.depsUpgradeOptions?.workflowOptions?.branches, + compilerDeps: compilerDependencies, + triageOptions: options.triageOptions, + }); if (options.backport ?? false) { new Backport(this, { branches: options.backportBranches, repoName }); diff --git a/test/projects/__snapshots__/jsii.test.ts.snap b/test/projects/__snapshots__/jsii.test.ts.snap index f5f9a946..daf3b358 100644 --- a/test/projects/__snapshots__/jsii.test.ts.snap +++ b/test/projects/__snapshots__/jsii.test.ts.snap @@ -5179,6 +5179,44 @@ test('hello', () => { } `; +exports[`can configure triage pr labels 1`] = ` +"# ~~ Generated by projen. To modify, edit .projenrc.js and run \\"npx projen\\". + +name: triage +on: + issues: + types: + - opened + pull_request: + types: + - opened +jobs: + assign-to-project: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + if: (github.repository == 'cdk8s-team/root') && (github.event.issue || (github.event.pull_request.user.login != 'cdk8s-automation' && github.event.pull_request.head.repo.full_name == github.repository)) + steps: + - uses: actions/add-to-project@v0.4.0 + with: + project-url: https://github.com/orgs/cdk8s-team/projects/12 + github-token: \${{ secrets.PROJEN_GITHUB_TOKEN }} + add-labels-to-pr: + runs-on: ubuntu-latest + permissions: + pull-requests: write + if: (github.repository == 'cdk8s-team/root') && (github.event.pull_request && github.event.pull_request.user.login != 'cdk8s-automation') + steps: + - uses: actions-ecosystem/action-add-labels@v1 + with: + labels: |- + label1 + label2 + github_token: \${{ secrets.PROJEN_GITHUB_TOKEN }} +" +`; + exports[`custom jsii project | disable publishing 1`] = ` Object { ".eslintrc.json": Object { diff --git a/test/projects/__snapshots__/node.test.ts.snap b/test/projects/__snapshots__/node.test.ts.snap index cf140aa1..c3d1d69a 100644 --- a/test/projects/__snapshots__/node.test.ts.snap +++ b/test/projects/__snapshots__/node.test.ts.snap @@ -1607,6 +1607,44 @@ echo \\"Configured core.hooksPath to \${hooksdir}\\" } `; +exports[`can configure triage pr labels 1`] = ` +"# ~~ Generated by projen. To modify, edit .projenrc.js and run \\"npx projen\\". + +name: triage +on: + issues: + types: + - opened + pull_request: + types: + - opened +jobs: + assign-to-project: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + if: (github.repository == 'cdk8s-team/root') && (github.event.issue || (github.event.pull_request.user.login != 'cdk8s-automation' && github.event.pull_request.head.repo.full_name == github.repository)) + steps: + - uses: actions/add-to-project@v0.4.0 + with: + project-url: https://github.com/orgs/cdk8s-team/projects/12 + github-token: \${{ secrets.PROJEN_GITHUB_TOKEN }} + add-labels-to-pr: + runs-on: ubuntu-latest + permissions: + pull-requests: write + if: (github.repository == 'cdk8s-team/root') && (github.event.pull_request && github.event.pull_request.user.login != 'cdk8s-automation') + steps: + - uses: actions-ecosystem/action-add-labels@v1 + with: + labels: |- + label1 + label2 + github_token: \${{ secrets.PROJEN_GITHUB_TOKEN }} +" +`; + exports[`custom node project 1`] = ` Object { ".gitattributes": "# ~~ Generated by projen. To modify, edit .projenrc.js and run \\"npx projen\\". diff --git a/test/projects/__snapshots__/typescript.test.ts.snap b/test/projects/__snapshots__/typescript.test.ts.snap index 5c5603a2..2803d3fb 100644 --- a/test/projects/__snapshots__/typescript.test.ts.snap +++ b/test/projects/__snapshots__/typescript.test.ts.snap @@ -4215,6 +4215,44 @@ test('hello', () => { } `; +exports[`can configure triage pr labels 1`] = ` +"# ~~ Generated by projen. To modify, edit .projenrc.js and run \\"npx projen\\". + +name: triage +on: + issues: + types: + - opened + pull_request: + types: + - opened +jobs: + assign-to-project: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + if: (github.repository == 'cdk8s-team/root') && (github.event.issue || (github.event.pull_request.user.login != 'cdk8s-automation' && github.event.pull_request.head.repo.full_name == github.repository)) + steps: + - uses: actions/add-to-project@v0.4.0 + with: + project-url: https://github.com/orgs/cdk8s-team/projects/12 + github-token: \${{ secrets.PROJEN_GITHUB_TOKEN }} + add-labels-to-pr: + runs-on: ubuntu-latest + permissions: + pull-requests: write + if: (github.repository == 'cdk8s-team/root') && (github.event.pull_request && github.event.pull_request.user.login != 'cdk8s-automation') + steps: + - uses: actions-ecosystem/action-add-labels@v1 + with: + labels: |- + label1 + label2 + github_token: \${{ secrets.PROJEN_GITHUB_TOKEN }} +" +`; + exports[`custom root typescript project 1`] = ` Object { ".eslintrc.json": Object { diff --git a/test/projects/jsii.test.ts b/test/projects/jsii.test.ts index ae01a3b5..aa1d5188 100644 --- a/test/projects/jsii.test.ts +++ b/test/projects/jsii.test.ts @@ -1,6 +1,20 @@ import { TaskRuntime, Testing } from 'projen'; import * as src from '../../src'; +test('can configure triage pr labels', () => { + + const project = new src.Cdk8sTeamJsiiProject({ + name: 'root', + defaultReleaseBranch: 'main', + triageOptions: { + prLabels: ['label1', 'label2'], + }, + }); + + const snapshot = Testing.synth(project); + expect(snapshot['.github/workflows/triage.yml']).toMatchSnapshot(); +}); + test('upgrade-runtime-dependencies includes bundled', () => { const project = new src.Cdk8sTeamJsiiProject({ diff --git a/test/projects/node.test.ts b/test/projects/node.test.ts index f3bdd890..3171c23b 100644 --- a/test/projects/node.test.ts +++ b/test/projects/node.test.ts @@ -1,6 +1,20 @@ import { TaskRuntime, Testing } from 'projen'; import * as src from '../../src'; +test('can configure triage pr labels', () => { + + const project = new src.Cdk8sTeamNodeProject({ + name: 'root', + defaultReleaseBranch: 'main', + triageOptions: { + prLabels: ['label1', 'label2'], + }, + }); + + const snapshot = Testing.synth(project); + expect(snapshot['.github/workflows/triage.yml']).toMatchSnapshot(); +}); + test('deps upgrade options are merged', () => { const project = new src.Cdk8sTeamNodeProject({ diff --git a/test/projects/typescript.test.ts b/test/projects/typescript.test.ts index 9324bb0d..ea219eef 100644 --- a/test/projects/typescript.test.ts +++ b/test/projects/typescript.test.ts @@ -1,6 +1,20 @@ import { TaskRuntime, Testing } from 'projen'; import * as src from '../../src'; +test('can configure triage pr labels', () => { + + const project = new src.Cdk8sTeamTypeScriptProject({ + name: 'root', + defaultReleaseBranch: 'main', + triageOptions: { + prLabels: ['label1', 'label2'], + }, + }); + + const snapshot = Testing.synth(project); + expect(snapshot['.github/workflows/triage.yml']).toMatchSnapshot(); +}); + test('upgrade-runtime-dependencies includes bundled', () => { const project = new src.Cdk8sTeamTypeScriptProject({