Skip to content

Commit

Permalink
feat: Exclude packages that has version set by Projen from upgrade ta…
Browse files Browse the repository at this point in the history
…sk (projen#1665)

fixes: projen#1659

---
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
  • Loading branch information
Hi-Fi authored Mar 8, 2022
1 parent 2f0c7f2 commit b2625a4
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 27 deletions.
10 changes: 5 additions & 5 deletions .projen/tasks.json

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

6 changes: 2 additions & 4 deletions src/javascript/node-project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -698,7 +698,6 @@ export class NodeProject extends GitHubProject {
);
ignoresProjen = dependabotConf?.ignoresProjen;
}

if (depsUpgrade) {
const defaultOptions: UpgradeDependenciesOptions = {
// if projen secret is defined we can also upgrade projen here.
Expand All @@ -715,12 +714,11 @@ export class NodeProject extends GitHubProject {
gitIdentity: this.workflowGitIdentity,
},
};
const upgradeDependencies = new UpgradeDependencies(
this.upgradeWorkflow = new UpgradeDependencies(
this,
deepMerge([defaultOptions, options.depsUpgradeOptions ?? {}])
);
ignoresProjen = upgradeDependencies.ignoresProjen;
this.upgradeWorkflow = upgradeDependencies;
ignoresProjen = this.upgradeWorkflow.ignoresProjen;
}

// create a dedicated workflow to upgrade projen itself if needed
Expand Down
61 changes: 43 additions & 18 deletions src/javascript/upgrade-dependencies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ export class UpgradeDependencies extends Component {

private readonly options: UpgradeDependenciesOptions;
private readonly _project: NodeProject;
private readonly _task: Task;
private readonly pullRequestTitle: string;

/**
Expand Down Expand Up @@ -126,17 +125,13 @@ export class UpgradeDependencies extends Component {
options.workflowOptions?.gitIdentity ?? DEFAULT_GITHUB_ACTIONS_USER;
this.postBuildSteps = [];
this.containerOptions = options.workflowOptions?.container;

project.addDevDeps("npm-check-updates@^12");

this.postUpgradeTask =
project.tasks.tryFind("post-upgrade") ??
project.tasks.addTask("post-upgrade", {
description: "Runs after upgrading dependencies",
});

// create the upgrade task
this._task = this.createTask();
}

/**
Expand All @@ -149,7 +144,12 @@ export class UpgradeDependencies extends Component {

// create a corresponding github workflow for each requested branch.
public preSynthesize() {
if (this._project.github && (this.options.workflow ?? true)) {
// Create task only here to consider also packages that are from extended classes
// Create task only if hasn't been overwritten manually
const task =
this._project.tasks.tryFind(this.options.taskName ?? "upgrade") ??
this.createTask();
if (task && this._project.github && (this.options.workflow ?? true)) {
// represents the default repository branch.
// just like not specifying anything.
const defaultBranch = undefined;
Expand All @@ -158,26 +158,51 @@ export class UpgradeDependencies extends Component {
this._project.release?.branches ?? [defaultBranch];
for (const branch of branches) {
this.workflows.push(
this.createWorkflow(this._task, this._project.github, branch)
this.createWorkflow(task, this._project.github, branch)
);
}
}
}

private createTask(): Task {
private createTask(): Task | undefined {
const taskName = this.options.taskName ?? "upgrade";

const exclude = this.options.exclude ?? [];
if (this.ignoresProjen) {
exclude.push("projen");
}

// exclude depedencies that has already version pinned (fully or with patch version) by Projen with ncu (but not package manager upgrade)
// Getting only unique values through set
const ncuExcludes = [
...new Set(
this.project.deps.all
.filter((dep) => dep.version && dep.version[0] !== "^")
.map((dep) => dep.name)
.concat(exclude)
),
];

const ncuIncludes = this.options.include?.filter(
(item) => !ncuExcludes.includes(item)
);

const includeLength = this.options.include?.length ?? 0;
const ncuIncludesLength = ncuIncludes?.length ?? 0;

// If all explicit includes already have version pinned, don't add task.
// Note that without explicit includes task gets added
if (includeLength > 0 && ncuIncludesLength === 0) {
return undefined;
}

const task = this._project.addTask(taskName, {
// this task should not run in CI mode because its designed to
// update package.json and lock files.
env: { CI: "0" },
description: this.pullRequestTitle,
});

const exclude = this.options.exclude ?? [];
if (this.ignoresProjen) {
exclude.push("projen");
}

for (const dep of ["dev", "optional", "peer", "prod", "bundle"]) {
const ncuCommand = [
"npm-check-updates",
Expand All @@ -186,11 +211,11 @@ export class UpgradeDependencies extends Component {
"--upgrade",
"--target=minor",
];
if (exclude.length > 0) {
ncuCommand.push(`--reject='${exclude.join(",")}'`);
}
if (this.options.include) {
ncuCommand.push(`--filter='${this.options.include.join(",")}'`);
// Don't add includes and excludes same time
if (ncuIncludes) {
ncuCommand.push(`--filter='${ncuIncludes.join(",")}'`);
} else if (ncuExcludes.length > 0) {
ncuCommand.push(`--reject='${ncuExcludes.join(",")}'`);
}

task.exec(ncuCommand.join(" "));
Expand Down
17 changes: 17 additions & 0 deletions test/cdk8s/cdk8s-app-project-ts.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as yaml from "yaml";
import { TaskRuntime } from "../../src";
import { Cdk8sTypeScriptApp } from "../../src/cdk8s";
import { synthSnapshot } from "../util";

Expand Down Expand Up @@ -160,3 +161,19 @@ test("cdk8sPlusVersion pinning", () => {
constructs: "^3.3.75",
});
});

test("upgrade task ignores pinned versions", () => {
const project = new Cdk8sTypeScriptApp({
cdk8sVersion: "1.0.0-beta.11",
name: "project",
defaultReleaseBranch: "main",
constructsVersionPinning: true,
cdk8sVersionPinning: true,
releaseWorkflow: true,
constructsVersion: "3.3.75",
});
const tasks = synthSnapshot(project)[TaskRuntime.MANIFEST_FILE].tasks;
expect(tasks.upgrade.steps[0].exec).toStrictEqual(
"npm-check-updates --dep dev --upgrade --target=minor --reject='cdk8s-cli,cdk8s,constructs,projen'"
);
});
14 changes: 14 additions & 0 deletions test/typescript/typescript.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { TaskRuntime } from "../../src";
import { PROJEN_RC } from "../../src/common";
import { mergeTsconfigOptions, TypeScriptProject } from "../../src/typescript";
import { synthSnapshot } from "../util";
Expand Down Expand Up @@ -164,3 +165,16 @@ test("projenrc.ts", () => {
steps: [{ exec: "ts-node --project tsconfig.dev.json .projenrc.ts" }],
});
});

test("upgrade task ignores pinned versions", () => {
const prj = new TypeScriptProject({
defaultReleaseBranch: "main",
name: "test",
deps: ["npm@^8"],
typescriptVersion: "4.4.4",
});
const tasks = synthSnapshot(prj)[TaskRuntime.MANIFEST_FILE].tasks;
expect(tasks.upgrade.steps[0].exec).toStrictEqual(
"npm-check-updates --dep dev --upgrade --target=minor --reject='typescript,projen'"
);
});
37 changes: 37 additions & 0 deletions test/upgrade-dependencies.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,43 @@ test("github runner can be customized", () => {
expect(upgrade.jobs.pr["runs-on"]).toEqual("self-hosted");
});

test("upgrade task created without projen defined versions at NodeProject", () => {
const prj = new NodeProject({
defaultReleaseBranch: "main",
name: "test project",
deps: ["npm@^8", "axios@~0.20.0", "markdownlint@0.24.0"],
});
const tasks = synthSnapshot(prj)[TaskRuntime.MANIFEST_FILE].tasks;
expect(tasks.upgrade.steps[0].exec).toStrictEqual(
"npm-check-updates --dep dev --upgrade --target=minor --reject='axios,markdownlint,projen'"
);
});

describe("projen-upgrade task is", () => {
test("not defined for Projen if version is set", () => {
const prj = new NodeProject({
defaultReleaseBranch: "main",
name: "test project",
packageName: "test-project",
projenVersion: "0.50.0",
});
const tasks = synthSnapshot(prj)[TaskRuntime.MANIFEST_FILE].tasks;
expect(tasks["upgrade-projen"]).toBeUndefined();
});

test("defined for Projen if version is not set", () => {
const prj = new NodeProject({
defaultReleaseBranch: "main",
name: "test project",
});
const tasks = synthSnapshot(prj)[TaskRuntime.MANIFEST_FILE].tasks;
expect(tasks["upgrade-projen"]).toBeDefined();
expect(tasks["upgrade-projen"].steps[0].exec).toStrictEqual(
"npm-check-updates --dep dev --upgrade --target=minor --filter='projen'"
);
});
});

function createProject(
options: Omit<
NodeProjectOptions,
Expand Down

0 comments on commit b2625a4

Please sign in to comment.