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
4 changes: 3 additions & 1 deletion .github/workflows/release.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions .projenrc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { configureEslint } from './projenrc/eslint';
import { IssueLabeler } from './projenrc/issue-labeler';
import { IssueRegressionLabeler } from './projenrc/issue-regression-labeler';
import { LargePrChecker } from './projenrc/large-pr-checker';
import { NpmPublishAfter } from './projenrc/npm-publish-after';
import { PrLabeler } from './projenrc/pr-labeler';
import { RecordPublishingTimestamp } from './projenrc/record-publishing-timestamp';
import { S3DocsPublishing } from './projenrc/s3-docs-publishing';
Expand Down Expand Up @@ -1794,6 +1795,10 @@ cliInteg.npmignore?.addPatterns('!resources/**/*');
cliInteg.postCompileTask.exec('yarn-cling');
cliInteg.gitignore.addPatterns('npm-shrinkwrap.json');

// cli-integ doesn't depend on aws-cdk, but its tests run against the published CLI.
// Don't publish it before the CLI is available.
new NpmPublishAfter(repoProject, cliInteg, [cli]);

// #endregion
//////////////////////////////////////////////////////////////////////
// #region shared setup
Expand Down
41 changes: 41 additions & 0 deletions projenrc/npm-publish-after.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import type { Monorepo } from 'cdklabs-projen-project-types/lib/yarn';
import type { Project, github } from 'projen';
import { Component } from 'projen';

/**
* Make a package's npm publish job wait for the npm publish jobs of other packages.
*
* Release jobs are ordered by declared package dependencies. Use this for
* ordering that isn't expressed as a dependency.
*/
export class NpmPublishAfter extends Component {
constructor(
private readonly project_: Monorepo,
private readonly pkg: Project,
private readonly after: Project[],
) {
super(project_);
}

public preSynthesize() {
const releaseWf = this.project_.github?.tryFindWorkflow('release');
if (!releaseWf) {
throw new Error('Could not find release workflow');
}

const jobId = npmJobId(this.pkg);
const job = releaseWf.getJob(jobId) as github.workflows.Job | undefined;
if (!job) {
throw new Error(`Could not find job ${jobId} in release workflow`);
}

releaseWf.updateJob(jobId, {
...job,
needs: [...(job.needs ?? []), ...this.after.map(npmJobId)],
});
}
}

function npmJobId(project: Project) {
Comment on lines +31 to +39

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Recommended — The after job ids appended to needs are never verified to exist as jobs in the workflow, unlike the target pkg job which is looked up via getJob and throws loudly if missing. A typo'd package, a non-publishing package (releaseToNpm: false), or a name with more than one / (since npmJobId uses non-global .replace) would silently emit a needs on a job id that does not exist. GitHub Actions then rejects the whole workflow at parse time — a late, confusing failure — rather than failing yarn projen synth. The current single use (@aws-cdk-testing/cli-integ after aws-cdk) derives correctly, so the harm is latent for future callers.

Suggested change: Resolve each after id with getJob and throw with the same clear message used for pkg when the job is missing, so a bad reference fails at synth. Only append ids that resolve to real jobs.

return `${project.name.replace('@', '').replace('/', '-')}_release_npm`;
}
Loading