mirror of
https://github.com/changesets/action
synced 2026-10-26 16:39:56 +08:00
Fixed an issue with ignored package being included in PR body incorrectly (#38)
This commit is contained in:
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://unpkg.com/@changesets/config@1.3.0/schema.json",
|
||||||
|
"ignore": ["ignored-package-pkg-a"]
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"private": true,
|
||||||
|
"name": "ignored-package",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"workspaces": [
|
||||||
|
"packages/*"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"name": "ignored-package-pkg-a",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"dependencies": {
|
||||||
|
"ignored-package-pkg-b": "1.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"name": "ignored-package-pkg-b",
|
||||||
|
"version": "1.0.0"
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://unpkg.com/@changesets/config@1.3.0/schema.json"
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"private": true,
|
||||||
|
"name": "simple-project",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"workspaces": [
|
||||||
|
"packages/*"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"name": "simple-project-pkg-a",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"dependencies": {
|
||||||
|
"simple-project-pkg-b": "1.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"name": "simple-project-pkg-b",
|
||||||
|
"version": "1.0.0"
|
||||||
|
}
|
||||||
Vendored
+781
-1191
File diff suppressed because one or more lines are too long
@@ -1,312 +0,0 @@
|
|||||||
import * as core from "@actions/core";
|
|
||||||
import { exec } from "@actions/exec";
|
|
||||||
import * as github from "@actions/github";
|
|
||||||
import fs from "fs-extra";
|
|
||||||
import { getPackages, Package } from "@manypkg/get-packages";
|
|
||||||
import path from "path";
|
|
||||||
import {
|
|
||||||
getChangelogEntry,
|
|
||||||
execWithOutput,
|
|
||||||
getChangedPackages,
|
|
||||||
sortTheThings,
|
|
||||||
} from "./utils";
|
|
||||||
import * as semver from "semver";
|
|
||||||
import { readPreState } from "@changesets/pre";
|
|
||||||
import readChangesets from "@changesets/read";
|
|
||||||
|
|
||||||
const createRelease = async (
|
|
||||||
octokit: github.GitHub,
|
|
||||||
{ pkg, tagName }: { pkg: Package; tagName: string }
|
|
||||||
) => {
|
|
||||||
try {
|
|
||||||
let changelogFileName = path.join(pkg.dir, "CHANGELOG.md");
|
|
||||||
|
|
||||||
let changelog = await fs.readFile(changelogFileName, "utf8");
|
|
||||||
|
|
||||||
let changelogEntry = getChangelogEntry(changelog, pkg.packageJson.version);
|
|
||||||
if (!changelogEntry) {
|
|
||||||
// we can find a changelog but not the entry for this version
|
|
||||||
// if this is true, something has probably gone wrong
|
|
||||||
return core.setFailed(
|
|
||||||
`Could not find changelog entry for ${pkg.packageJson.name}@${pkg.packageJson.version}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
await octokit.repos.createRelease({
|
|
||||||
tag_name: tagName,
|
|
||||||
body: changelogEntry.content,
|
|
||||||
prerelease: pkg.packageJson.version.includes("-"),
|
|
||||||
...github.context.repo,
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
// if we can't find a changelog, the user has probably disabled changelogs
|
|
||||||
if (err.code !== "ENOENT") {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
(async () => {
|
|
||||||
let githubToken = process.env.GITHUB_TOKEN;
|
|
||||||
|
|
||||||
if (!githubToken) {
|
|
||||||
core.setFailed("Please add the GITHUB_TOKEN to the changesets action");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let repo = `${github.context.repo.owner}/${github.context.repo.repo}`;
|
|
||||||
let branch = github.context.ref.replace("refs/heads/", "");
|
|
||||||
let preState = await readPreState(process.cwd());
|
|
||||||
|
|
||||||
let isInPreMode = preState !== undefined && preState.mode === "pre";
|
|
||||||
|
|
||||||
const octokit = new github.GitHub(githubToken);
|
|
||||||
|
|
||||||
console.log("setting git user");
|
|
||||||
await exec("git", [
|
|
||||||
"config",
|
|
||||||
"--global",
|
|
||||||
"user.name",
|
|
||||||
`"github-actions[bot]"`,
|
|
||||||
]);
|
|
||||||
await exec("git", [
|
|
||||||
"config",
|
|
||||||
"--global",
|
|
||||||
"user.email",
|
|
||||||
`"github-actions[bot]@users.noreply.github.com"`,
|
|
||||||
]);
|
|
||||||
|
|
||||||
console.log("setting GitHub credentials");
|
|
||||||
await fs.writeFile(
|
|
||||||
`${process.env.HOME}/.netrc`,
|
|
||||||
`machine github.com\nlogin github-actions[bot]\npassword ${githubToken}`
|
|
||||||
);
|
|
||||||
|
|
||||||
let changesets = await readChangesets(process.cwd());
|
|
||||||
|
|
||||||
if (isInPreMode) {
|
|
||||||
let changesetsToFilter = new Set(preState.changesets);
|
|
||||||
changesets = changesets.filter((x) => !changesetsToFilter.has(x.id));
|
|
||||||
}
|
|
||||||
|
|
||||||
let hasChangesets = changesets.length !== 0;
|
|
||||||
|
|
||||||
let inputs = {
|
|
||||||
publishScript: core.getInput("publish"),
|
|
||||||
versionScript: core.getInput("version"),
|
|
||||||
commit: core.getInput("commit") || "Version Packages",
|
|
||||||
prTitle: core.getInput("title") || "Version Packages",
|
|
||||||
};
|
|
||||||
core.setOutput("published", "false");
|
|
||||||
core.setOutput("publishedPackages", "[]");
|
|
||||||
|
|
||||||
if (!hasChangesets && !inputs.publishScript) {
|
|
||||||
console.log("No changesets found");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!hasChangesets && inputs.publishScript) {
|
|
||||||
console.log(
|
|
||||||
"No changesets found, attempting to publish any unpublished packages to npm"
|
|
||||||
);
|
|
||||||
let npmrcPath = `${process.env.HOME}/.npmrc`;
|
|
||||||
if (fs.existsSync(npmrcPath)) {
|
|
||||||
console.log("Found existing .npmrc file");
|
|
||||||
} else {
|
|
||||||
console.log("No .npmrc file found, creating one");
|
|
||||||
fs.writeFileSync(
|
|
||||||
npmrcPath,
|
|
||||||
`//registry.npmjs.org/:_authToken=${process.env.NPM_TOKEN}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let [publishCommand, ...publishArgs] = inputs.publishScript.split(/\s+/);
|
|
||||||
|
|
||||||
let changesetPublishOutput = await execWithOutput(
|
|
||||||
publishCommand,
|
|
||||||
publishArgs
|
|
||||||
);
|
|
||||||
|
|
||||||
await exec("git", ["pull", "origin", branch]);
|
|
||||||
|
|
||||||
await exec("git", ["push", "origin", `HEAD:${branch}`, "--tags"]);
|
|
||||||
|
|
||||||
let { packages, tool } = await getPackages(process.cwd());
|
|
||||||
let releasedPackages: Package[] = [];
|
|
||||||
|
|
||||||
if (tool !== "root") {
|
|
||||||
let newTagRegex = /New tag:\s+(@[^/]+\/[^@]+|[^/]+)@([^\s]+)/;
|
|
||||||
let packagesByName = new Map(
|
|
||||||
packages.map((x) => [x.packageJson.name, x])
|
|
||||||
);
|
|
||||||
|
|
||||||
for (let line of changesetPublishOutput.stdout.split("\n")) {
|
|
||||||
let match = line.match(newTagRegex);
|
|
||||||
if (match === null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let pkgName = match[1];
|
|
||||||
let pkg = packagesByName.get(pkgName);
|
|
||||||
if (pkg === undefined) {
|
|
||||||
return core.setFailed(
|
|
||||||
`Package "${pkgName}" not found.` +
|
|
||||||
"This is probably a bug in the action, please open an issue"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
releasedPackages.push(pkg);
|
|
||||||
}
|
|
||||||
|
|
||||||
await Promise.all(
|
|
||||||
releasedPackages.map((pkg) =>
|
|
||||||
createRelease(octokit, {
|
|
||||||
pkg,
|
|
||||||
tagName: `${pkg.packageJson.name}@${pkg.packageJson.version}`,
|
|
||||||
})
|
|
||||||
)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
if (packages.length === 0) {
|
|
||||||
return core.setFailed(
|
|
||||||
`No package found.` +
|
|
||||||
"This is probably a bug in the action, please open an issue"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
const pkg = packages[0];
|
|
||||||
releasedPackages.push(pkg);
|
|
||||||
await createRelease(octokit, {
|
|
||||||
pkg,
|
|
||||||
tagName: `v${pkg.packageJson.version}`,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (releasedPackages.length) {
|
|
||||||
core.setOutput("published", "true");
|
|
||||||
core.setOutput(
|
|
||||||
"publishedPackages",
|
|
||||||
JSON.stringify(
|
|
||||||
releasedPackages.map((pkg) => ({
|
|
||||||
name: pkg.packageJson.name,
|
|
||||||
version: pkg.packageJson.version,
|
|
||||||
}))
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasChangesets) {
|
|
||||||
let versionBranch = `changeset-release/${branch}`;
|
|
||||||
let { stderr } = await execWithOutput("git", ["checkout", versionBranch], {
|
|
||||||
ignoreReturnCode: true,
|
|
||||||
});
|
|
||||||
let isCreatingChangesetReleaseBranch = !stderr
|
|
||||||
.toString()
|
|
||||||
.includes(`Switched to a new branch '${versionBranch}'`);
|
|
||||||
if (isCreatingChangesetReleaseBranch) {
|
|
||||||
await exec("git", ["checkout", "-b", versionBranch]);
|
|
||||||
}
|
|
||||||
|
|
||||||
await exec("git", ["reset", "--hard", github.context.sha]);
|
|
||||||
|
|
||||||
if (inputs.versionScript) {
|
|
||||||
let [versionCommand, ...versionArgs] = inputs.versionScript.split(/\s+/);
|
|
||||||
await exec(versionCommand, versionArgs);
|
|
||||||
} else {
|
|
||||||
let changesetsCliPkgJson = await fs.readJson(
|
|
||||||
path.join("node_modules", "@changesets", "cli", "package.json")
|
|
||||||
);
|
|
||||||
let cmd = semver.lt(changesetsCliPkgJson.version, "2.0.0")
|
|
||||||
? "bump"
|
|
||||||
: "version";
|
|
||||||
await exec("node", ["./node_modules/@changesets/cli/bin.js", cmd]);
|
|
||||||
}
|
|
||||||
|
|
||||||
let searchQuery = `repo:${repo}+state:open+head:${versionBranch}+base:${branch}`;
|
|
||||||
let searchResultPromise = octokit.search.issuesAndPullRequests({
|
|
||||||
q: searchQuery,
|
|
||||||
});
|
|
||||||
let changedPackages = await getChangedPackages(process.cwd());
|
|
||||||
|
|
||||||
let prBodyPromise = (async () => {
|
|
||||||
return (
|
|
||||||
`This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and ${
|
|
||||||
inputs.publishScript
|
|
||||||
? `the packages will be published to npm automatically`
|
|
||||||
: `publish to npm yourself or [setup this action to publish automatically](https://github.com/changesets/action#with-publishing)`
|
|
||||||
}. If you're not ready to do a release yet, that's fine, whenever you add more changesets to ${branch}, this PR will be updated.
|
|
||||||
${
|
|
||||||
isInPreMode
|
|
||||||
? `
|
|
||||||
⚠️⚠️⚠️⚠️⚠️⚠️
|
|
||||||
|
|
||||||
\`${branch}\` is currently in **pre mode** so this branch has prereleases rather than normal releases. If you want to exit prereleases, run \`changeset pre exit\` on \`${branch}\`.
|
|
||||||
|
|
||||||
⚠️⚠️⚠️⚠️⚠️⚠️
|
|
||||||
`
|
|
||||||
: ""
|
|
||||||
}
|
|
||||||
# Releases
|
|
||||||
` +
|
|
||||||
(
|
|
||||||
await Promise.all(
|
|
||||||
changedPackages.map(async (pkg) => {
|
|
||||||
let changelogContents = await fs.readFile(
|
|
||||||
path.join(pkg.dir, "CHANGELOG.md"),
|
|
||||||
"utf8"
|
|
||||||
);
|
|
||||||
|
|
||||||
let entry = getChangelogEntry(
|
|
||||||
changelogContents,
|
|
||||||
pkg.packageJson.version
|
|
||||||
);
|
|
||||||
return {
|
|
||||||
highestLevel: entry.highestLevel,
|
|
||||||
private: !!pkg.packageJson.private,
|
|
||||||
content:
|
|
||||||
`## ${pkg.packageJson.name}@${pkg.packageJson.version}\n\n` +
|
|
||||||
entry.content,
|
|
||||||
};
|
|
||||||
})
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.filter((x) => x)
|
|
||||||
.sort(sortTheThings)
|
|
||||||
.map((x) => x.content)
|
|
||||||
.join("\n ")
|
|
||||||
);
|
|
||||||
})();
|
|
||||||
|
|
||||||
const prTitle = `${inputs.prTitle}${
|
|
||||||
isInPreMode ? ` (${preState.tag})` : ""
|
|
||||||
}`;
|
|
||||||
const commitMsg = `${inputs.commit}${
|
|
||||||
isInPreMode ? ` (${preState.tag})` : ""
|
|
||||||
}`;
|
|
||||||
|
|
||||||
await exec("git", ["add", "."]);
|
|
||||||
await exec("git", ["commit", "-m", commitMsg]);
|
|
||||||
await exec("git", ["push", "origin", versionBranch, "--force"]);
|
|
||||||
let searchResult = await searchResultPromise;
|
|
||||||
console.log(JSON.stringify(searchResult.data, null, 2));
|
|
||||||
if (searchResult.data.items.length === 0) {
|
|
||||||
console.log("creating pull request");
|
|
||||||
await octokit.pulls.create({
|
|
||||||
base: branch,
|
|
||||||
head: versionBranch,
|
|
||||||
title: prTitle,
|
|
||||||
body: await prBodyPromise,
|
|
||||||
...github.context.repo,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
octokit.pulls.update({
|
|
||||||
pull_number: searchResult.data.items[0].number,
|
|
||||||
title: prTitle,
|
|
||||||
body: await prBodyPromise,
|
|
||||||
...github.context.repo,
|
|
||||||
});
|
|
||||||
console.log("pull request found");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})().catch((err) => {
|
|
||||||
console.error(err);
|
|
||||||
core.setFailed(err.message);
|
|
||||||
});
|
|
||||||
+7
-4
@@ -4,12 +4,16 @@
|
|||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@changesets/cli": "^2.9.1",
|
||||||
|
"@changesets/write": "^0.1.3",
|
||||||
|
"fixturez": "^1.1.0",
|
||||||
"parcel": "^1.12.3",
|
"parcel": "^1.12.3",
|
||||||
"prettier": "^2.0.5",
|
"prettier": "^2.0.5",
|
||||||
"typescript": "^3.5.3"
|
"typescript": "^3.5.3"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "parcel build ./index.ts --no-source-maps --target=node --bundle-node-modules"
|
"build": "parcel build ./src/index.ts --no-source-maps --target=node --bundle-node-modules",
|
||||||
|
"test:watch": "jest --watch"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^1.0.0",
|
"@actions/core": "^1.0.0",
|
||||||
@@ -18,8 +22,8 @@
|
|||||||
"@babel/core": "^7.6.0",
|
"@babel/core": "^7.6.0",
|
||||||
"@babel/preset-env": "^7.6.0",
|
"@babel/preset-env": "^7.6.0",
|
||||||
"@babel/preset-typescript": "^7.6.0",
|
"@babel/preset-typescript": "^7.6.0",
|
||||||
"@changesets/pre": "^0.2.0",
|
"@changesets/pre": "^1.0.4",
|
||||||
"@changesets/read": "^0.4.1",
|
"@changesets/read": "^0.4.6",
|
||||||
"@manypkg/get-packages": "^1.0.1",
|
"@manypkg/get-packages": "^1.0.1",
|
||||||
"@types/fs-extra": "^8.0.0",
|
"@types/fs-extra": "^8.0.0",
|
||||||
"@types/jest": "^24.0.18",
|
"@types/jest": "^24.0.18",
|
||||||
@@ -33,7 +37,6 @@
|
|||||||
"remark-parse": "^7.0.1",
|
"remark-parse": "^7.0.1",
|
||||||
"remark-stringify": "^7.0.3",
|
"remark-stringify": "^7.0.3",
|
||||||
"semver": "^6.3.0",
|
"semver": "^6.3.0",
|
||||||
"tempy": "^0.3.0",
|
|
||||||
"unified": "^8.3.2"
|
"unified": "^8.3.2"
|
||||||
},
|
},
|
||||||
"husky": {
|
"husky": {
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`version creates simple PR 1`] = `
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"base": "some-branch",
|
||||||
|
"body": "This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and publish to npm yourself or [setup this action to publish automatically](https://github.com/changesets/action#with-publishing). If you're not ready to do a release yet, that's fine, whenever you add more changesets to some-branch, this PR will be updated.
|
||||||
|
|
||||||
|
# Releases
|
||||||
|
## simple-project-pkg-a@1.1.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- Awesome feature
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [undefined]
|
||||||
|
- simple-project-pkg-b@1.1.0
|
||||||
|
|
||||||
|
## simple-project-pkg-b@1.1.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- Awesome feature
|
||||||
|
",
|
||||||
|
"head": "changeset-release/some-branch",
|
||||||
|
"owner": "changesets",
|
||||||
|
"repo": "action",
|
||||||
|
"title": "Version Packages",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`version doesn't include ignored package that got a dependency update in the PR body 1`] = `
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"base": "some-branch",
|
||||||
|
"body": "This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and publish to npm yourself or [setup this action to publish automatically](https://github.com/changesets/action#with-publishing). If you're not ready to do a release yet, that's fine, whenever you add more changesets to some-branch, this PR will be updated.
|
||||||
|
|
||||||
|
# Releases
|
||||||
|
## ignored-package-pkg-b@1.1.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- Awesome feature
|
||||||
|
",
|
||||||
|
"head": "changeset-release/some-branch",
|
||||||
|
"owner": "changesets",
|
||||||
|
"repo": "action",
|
||||||
|
"title": "Version Packages",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`version only includes bumped packages in the PR body 1`] = `
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"base": "some-branch",
|
||||||
|
"body": "This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and publish to npm yourself or [setup this action to publish automatically](https://github.com/changesets/action#with-publishing). If you're not ready to do a release yet, that's fine, whenever you add more changesets to some-branch, this PR will be updated.
|
||||||
|
|
||||||
|
# Releases
|
||||||
|
## simple-project-pkg-a@1.1.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- Awesome feature
|
||||||
|
",
|
||||||
|
"head": "changeset-release/some-branch",
|
||||||
|
"owner": "changesets",
|
||||||
|
"repo": "action",
|
||||||
|
"title": "Version Packages",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
`;
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
import { exec } from "@actions/exec";
|
||||||
|
import { execWithOutput } from "./utils";
|
||||||
|
|
||||||
|
export const setupUser = async () => {
|
||||||
|
await exec("git", [
|
||||||
|
"config",
|
||||||
|
"--global",
|
||||||
|
"user.name",
|
||||||
|
`"github-actions[bot]"`,
|
||||||
|
]);
|
||||||
|
await exec("git", [
|
||||||
|
"config",
|
||||||
|
"--global",
|
||||||
|
"user.email",
|
||||||
|
`"github-actions[bot]@users.noreply.github.com"`,
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const pullBranch = async (branch: string) => {
|
||||||
|
await exec("git", ["pull", "origin", branch]);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const push = async (
|
||||||
|
branch: string,
|
||||||
|
{ force, includeTags }: { force?: boolean; includeTags?: boolean } = {}
|
||||||
|
) => {
|
||||||
|
await exec(
|
||||||
|
"git",
|
||||||
|
[
|
||||||
|
"push",
|
||||||
|
"origin",
|
||||||
|
`HEAD:${branch}`,
|
||||||
|
includeTags && "--tags",
|
||||||
|
force && "--force",
|
||||||
|
].filter<string>(Boolean as any)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const switchToMaybeExistingBranch = async (branch: string) => {
|
||||||
|
let { stderr } = await execWithOutput("git", ["checkout", branch], {
|
||||||
|
ignoreReturnCode: true,
|
||||||
|
});
|
||||||
|
let isCreatingBranch = !stderr
|
||||||
|
.toString()
|
||||||
|
.includes(`Switched to a new branch '${branch}'`);
|
||||||
|
if (isCreatingBranch) {
|
||||||
|
await exec("git", ["checkout", "-b", branch]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const reset = async (
|
||||||
|
pathSpec: string,
|
||||||
|
mode: "hard" | "soft" | "mixed" = "hard"
|
||||||
|
) => {
|
||||||
|
await exec("git", ["reset", `--${mode}`, pathSpec]);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const commitAll = async (message: string) => {
|
||||||
|
await exec("git", ["add", "."]);
|
||||||
|
await exec("git", ["commit", "-m", message]);
|
||||||
|
};
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
import * as core from "@actions/core";
|
||||||
|
import fs from "fs-extra";
|
||||||
|
import * as gitUtils from "./gitUtils";
|
||||||
|
import { runPublish, runVersion } from "./run";
|
||||||
|
import readChangesetState from "./readChangesetState";
|
||||||
|
|
||||||
|
const getOptionalInput = (name: string) => core.getInput(name) || undefined;
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
let githubToken = process.env.GITHUB_TOKEN;
|
||||||
|
|
||||||
|
if (!githubToken) {
|
||||||
|
core.setFailed("Please add the GITHUB_TOKEN to the changesets action");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
core.setOutput("published", "false");
|
||||||
|
core.setOutput("publishedPackages", "[]");
|
||||||
|
|
||||||
|
console.log("setting git user");
|
||||||
|
await gitUtils.setupUser();
|
||||||
|
|
||||||
|
console.log("setting GitHub credentials");
|
||||||
|
await fs.writeFile(
|
||||||
|
`${process.env.HOME}/.netrc`,
|
||||||
|
`machine github.com\nlogin github-actions[bot]\npassword ${githubToken}`
|
||||||
|
);
|
||||||
|
|
||||||
|
let { changesets } = await readChangesetState();
|
||||||
|
|
||||||
|
let publishScript = core.getInput("publish");
|
||||||
|
let hasChangesets = changesets.length !== 0;
|
||||||
|
let hasPublishScript = !!publishScript;
|
||||||
|
|
||||||
|
switch (true) {
|
||||||
|
case !hasChangesets && !hasPublishScript:
|
||||||
|
console.log("No changesets found");
|
||||||
|
return;
|
||||||
|
case !hasChangesets && hasPublishScript: {
|
||||||
|
console.log(
|
||||||
|
"No changesets found, attempting to publish any unpublished packages to npm"
|
||||||
|
);
|
||||||
|
|
||||||
|
let npmrcPath = `${process.env.HOME}/.npmrc`;
|
||||||
|
if (fs.existsSync(npmrcPath)) {
|
||||||
|
console.log("Found existing .npmrc file");
|
||||||
|
} else {
|
||||||
|
console.log("No .npmrc file found, creating one");
|
||||||
|
fs.writeFileSync(
|
||||||
|
npmrcPath,
|
||||||
|
`//registry.npmjs.org/:_authToken=${process.env.NPM_TOKEN}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await runPublish({
|
||||||
|
script: publishScript,
|
||||||
|
githubToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (result.published) {
|
||||||
|
core.setOutput("published", "true");
|
||||||
|
core.setOutput(
|
||||||
|
"publishedPackages",
|
||||||
|
JSON.stringify(result.publishedPackages)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case hasChangesets:
|
||||||
|
await runVersion({
|
||||||
|
script: getOptionalInput("version"),
|
||||||
|
githubToken,
|
||||||
|
prTitle: getOptionalInput("title"),
|
||||||
|
commitMessage: getOptionalInput("commit"),
|
||||||
|
hasPublishScript,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
})().catch((err) => {
|
||||||
|
console.error(err);
|
||||||
|
core.setFailed(err.message);
|
||||||
|
});
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import { PreState, NewChangeset } from "@changesets/types";
|
||||||
|
import { readPreState } from "@changesets/pre";
|
||||||
|
import readChangesets from "@changesets/read";
|
||||||
|
|
||||||
|
export type ChangesetState = {
|
||||||
|
preState: PreState | undefined;
|
||||||
|
changesets: NewChangeset[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export default async function readChangesetState(
|
||||||
|
cwd: string = process.cwd()
|
||||||
|
): Promise<ChangesetState> {
|
||||||
|
let preState = await readPreState(cwd);
|
||||||
|
let isInPreMode = preState !== undefined && preState.mode === "pre";
|
||||||
|
|
||||||
|
let changesets = await readChangesets(cwd);
|
||||||
|
|
||||||
|
if (isInPreMode) {
|
||||||
|
let changesetsToFilter = new Set(preState.changesets);
|
||||||
|
changesets = changesets.filter((x) => !changesetsToFilter.has(x.id));
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
preState: isInPreMode ? preState : undefined,
|
||||||
|
changesets,
|
||||||
|
};
|
||||||
|
}
|
||||||
+148
@@ -0,0 +1,148 @@
|
|||||||
|
import fixturez from "fixturez";
|
||||||
|
import * as github from "@actions/github";
|
||||||
|
import fs from "fs-extra";
|
||||||
|
import path from "path";
|
||||||
|
import writeChangeset from "@changesets/write";
|
||||||
|
import { Changeset } from "@changesets/types";
|
||||||
|
import { runVersion } from "./run";
|
||||||
|
|
||||||
|
jest.mock("@actions/github", () => ({
|
||||||
|
context: {
|
||||||
|
repo: {
|
||||||
|
owner: "changesets",
|
||||||
|
repo: "action",
|
||||||
|
},
|
||||||
|
ref: "refs/heads/some-branch",
|
||||||
|
sha: "xeac7",
|
||||||
|
},
|
||||||
|
GitHub: jest.fn(),
|
||||||
|
}));
|
||||||
|
jest.mock("./gitUtils");
|
||||||
|
|
||||||
|
let mockedGithubMethods = {
|
||||||
|
search: {
|
||||||
|
issuesAndPullRequests: jest.fn(),
|
||||||
|
},
|
||||||
|
pulls: {
|
||||||
|
create: jest.fn(),
|
||||||
|
},
|
||||||
|
repos: {
|
||||||
|
createRelease: jest.fn(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
(github.GitHub as any).mockImplementation(() => mockedGithubMethods);
|
||||||
|
|
||||||
|
let f = fixturez(__dirname);
|
||||||
|
|
||||||
|
const linkNodeModules = async (cwd: string) => {
|
||||||
|
await fs.symlink(
|
||||||
|
path.join(__dirname, "..", "node_modules"),
|
||||||
|
path.join(cwd, "node_modules")
|
||||||
|
);
|
||||||
|
};
|
||||||
|
const writeChangesets = (changesets: Changeset[], cwd: string) => {
|
||||||
|
return Promise.all(changesets.map((commit) => writeChangeset(commit, cwd)));
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("version", () => {
|
||||||
|
it("creates simple PR", async () => {
|
||||||
|
let cwd = f.copy("simple-project");
|
||||||
|
linkNodeModules(cwd);
|
||||||
|
|
||||||
|
mockedGithubMethods.search.issuesAndPullRequests.mockImplementationOnce(
|
||||||
|
() => ({ data: { items: [] } })
|
||||||
|
);
|
||||||
|
|
||||||
|
await writeChangesets(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
releases: [
|
||||||
|
{
|
||||||
|
name: "simple-project-pkg-a",
|
||||||
|
type: "minor",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "simple-project-pkg-b",
|
||||||
|
type: "minor",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
summary: "Awesome feature",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
cwd
|
||||||
|
);
|
||||||
|
|
||||||
|
await runVersion({
|
||||||
|
githubToken: "@@GITHUB_TOKEN",
|
||||||
|
cwd,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(mockedGithubMethods.pulls.create.mock.calls[0]).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("only includes bumped packages in the PR body", async () => {
|
||||||
|
let cwd = f.copy("simple-project");
|
||||||
|
linkNodeModules(cwd);
|
||||||
|
|
||||||
|
mockedGithubMethods.search.issuesAndPullRequests.mockImplementationOnce(
|
||||||
|
() => ({ data: { items: [] } })
|
||||||
|
);
|
||||||
|
|
||||||
|
await writeChangesets(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
releases: [
|
||||||
|
{
|
||||||
|
name: "simple-project-pkg-a",
|
||||||
|
type: "minor",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
summary: "Awesome feature",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
cwd
|
||||||
|
);
|
||||||
|
|
||||||
|
await runVersion({
|
||||||
|
githubToken: "@@GITHUB_TOKEN",
|
||||||
|
cwd,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(mockedGithubMethods.pulls.create.mock.calls[0]).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("doesn't include ignored package that got a dependency update in the PR body", async () => {
|
||||||
|
let cwd = f.copy("ignored-package");
|
||||||
|
linkNodeModules(cwd);
|
||||||
|
|
||||||
|
mockedGithubMethods.search.issuesAndPullRequests.mockImplementationOnce(
|
||||||
|
() => ({ data: { items: [] } })
|
||||||
|
);
|
||||||
|
|
||||||
|
await writeChangesets(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
releases: [
|
||||||
|
{
|
||||||
|
name: "ignored-package-pkg-b",
|
||||||
|
type: "minor",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
summary: "Awesome feature",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
cwd
|
||||||
|
);
|
||||||
|
|
||||||
|
await runVersion({
|
||||||
|
githubToken: "@@GITHUB_TOKEN",
|
||||||
|
cwd,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(mockedGithubMethods.pulls.create.mock.calls[0]).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
+272
@@ -0,0 +1,272 @@
|
|||||||
|
import { exec } from "@actions/exec";
|
||||||
|
import * as github from "@actions/github";
|
||||||
|
import fs from "fs-extra";
|
||||||
|
import { getPackages, Package } from "@manypkg/get-packages";
|
||||||
|
import path from "path";
|
||||||
|
import * as semver from "semver";
|
||||||
|
import {
|
||||||
|
getChangelogEntry,
|
||||||
|
execWithOutput,
|
||||||
|
getChangedPackages,
|
||||||
|
sortTheThings,
|
||||||
|
getVersionsByDirectory,
|
||||||
|
} from "./utils";
|
||||||
|
import * as gitUtils from "./gitUtils";
|
||||||
|
import readChangesetState from "./readChangesetState";
|
||||||
|
|
||||||
|
const createRelease = async (
|
||||||
|
octokit: github.GitHub,
|
||||||
|
{ pkg, tagName }: { pkg: Package; tagName: string }
|
||||||
|
) => {
|
||||||
|
try {
|
||||||
|
let changelogFileName = path.join(pkg.dir, "CHANGELOG.md");
|
||||||
|
|
||||||
|
let changelog = await fs.readFile(changelogFileName, "utf8");
|
||||||
|
|
||||||
|
let changelogEntry = getChangelogEntry(changelog, pkg.packageJson.version);
|
||||||
|
if (!changelogEntry) {
|
||||||
|
// we can find a changelog but not the entry for this version
|
||||||
|
// if this is true, something has probably gone wrong
|
||||||
|
throw new Error(
|
||||||
|
`Could not find changelog entry for ${pkg.packageJson.name}@${pkg.packageJson.version}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await octokit.repos.createRelease({
|
||||||
|
tag_name: tagName,
|
||||||
|
body: changelogEntry.content,
|
||||||
|
prerelease: pkg.packageJson.version.includes("-"),
|
||||||
|
...github.context.repo,
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
// if we can't find a changelog, the user has probably disabled changelogs
|
||||||
|
if (err.code !== "ENOENT") {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
type PublishOptions = {
|
||||||
|
script: string;
|
||||||
|
githubToken: string;
|
||||||
|
cwd?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type PublishedPackage = { name: string; version: string };
|
||||||
|
|
||||||
|
type PublishResult =
|
||||||
|
| {
|
||||||
|
published: true;
|
||||||
|
publishedPackages: PublishedPackage[];
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
published: false;
|
||||||
|
};
|
||||||
|
|
||||||
|
export async function runPublish({
|
||||||
|
script,
|
||||||
|
githubToken,
|
||||||
|
cwd = process.cwd(),
|
||||||
|
}: PublishOptions): Promise<PublishResult> {
|
||||||
|
let branch = github.context.ref.replace("refs/heads/", "");
|
||||||
|
let octokit = new github.GitHub(githubToken);
|
||||||
|
let [publishCommand, ...publishArgs] = script.split(/\s+/);
|
||||||
|
|
||||||
|
let changesetPublishOutput = await execWithOutput(
|
||||||
|
publishCommand,
|
||||||
|
publishArgs,
|
||||||
|
{ cwd }
|
||||||
|
);
|
||||||
|
|
||||||
|
await gitUtils.pullBranch(branch);
|
||||||
|
await gitUtils.push(branch, { includeTags: true });
|
||||||
|
|
||||||
|
let { packages, tool } = await getPackages(cwd);
|
||||||
|
let releasedPackages: Package[] = [];
|
||||||
|
|
||||||
|
if (tool !== "root") {
|
||||||
|
let newTagRegex = /New tag:\s+(@[^/]+\/[^@]+|[^/]+)@([^\s]+)/;
|
||||||
|
let packagesByName = new Map(packages.map((x) => [x.packageJson.name, x]));
|
||||||
|
|
||||||
|
for (let line of changesetPublishOutput.stdout.split("\n")) {
|
||||||
|
let match = line.match(newTagRegex);
|
||||||
|
if (match === null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let pkgName = match[1];
|
||||||
|
let pkg = packagesByName.get(pkgName);
|
||||||
|
if (pkg === undefined) {
|
||||||
|
throw new Error(
|
||||||
|
`Package "${pkgName}" not found.` +
|
||||||
|
"This is probably a bug in the action, please open an issue"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
releasedPackages.push(pkg);
|
||||||
|
}
|
||||||
|
|
||||||
|
await Promise.all(
|
||||||
|
releasedPackages.map((pkg) =>
|
||||||
|
createRelease(octokit, {
|
||||||
|
pkg,
|
||||||
|
tagName: `${pkg.packageJson.name}@${pkg.packageJson.version}`,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
if (packages.length === 0) {
|
||||||
|
throw new Error(
|
||||||
|
`No package found.` +
|
||||||
|
"This is probably a bug in the action, please open an issue"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const pkg = packages[0];
|
||||||
|
releasedPackages.push(pkg);
|
||||||
|
await createRelease(octokit, {
|
||||||
|
pkg,
|
||||||
|
tagName: `v${pkg.packageJson.version}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (releasedPackages.length) {
|
||||||
|
return {
|
||||||
|
published: true,
|
||||||
|
publishedPackages: releasedPackages.map((pkg) => ({
|
||||||
|
name: pkg.packageJson.name,
|
||||||
|
version: pkg.packageJson.version,
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return { published: false };
|
||||||
|
}
|
||||||
|
|
||||||
|
type VersionOptions = {
|
||||||
|
script?: string;
|
||||||
|
githubToken: string;
|
||||||
|
cwd?: string;
|
||||||
|
prTitle?: string;
|
||||||
|
commitMessage?: string;
|
||||||
|
hasPublishScript?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export async function runVersion({
|
||||||
|
script,
|
||||||
|
githubToken,
|
||||||
|
cwd = process.cwd(),
|
||||||
|
prTitle = "Version Packages",
|
||||||
|
commitMessage = "Version Packages",
|
||||||
|
hasPublishScript = false,
|
||||||
|
}: VersionOptions) {
|
||||||
|
let repo = `${github.context.repo.owner}/${github.context.repo.repo}`;
|
||||||
|
let branch = github.context.ref.replace("refs/heads/", "");
|
||||||
|
let versionBranch = `changeset-release/${branch}`;
|
||||||
|
let octokit = new github.GitHub(githubToken);
|
||||||
|
let { preState } = await readChangesetState(cwd);
|
||||||
|
|
||||||
|
await gitUtils.switchToMaybeExistingBranch(versionBranch);
|
||||||
|
await gitUtils.reset(github.context.sha);
|
||||||
|
|
||||||
|
let versionsByDirectory = await getVersionsByDirectory(cwd);
|
||||||
|
|
||||||
|
if (script) {
|
||||||
|
let [versionCommand, ...versionArgs] = script.split(/\s+/);
|
||||||
|
await exec(versionCommand, versionArgs, { cwd });
|
||||||
|
} else {
|
||||||
|
// technically
|
||||||
|
let changesetsCliPkgJson = await require(path.join(
|
||||||
|
cwd,
|
||||||
|
"node_modules",
|
||||||
|
"@changesets",
|
||||||
|
"cli",
|
||||||
|
"package.json"
|
||||||
|
));
|
||||||
|
let cmd = semver.lt(changesetsCliPkgJson.version, "2.0.0")
|
||||||
|
? "bump"
|
||||||
|
: "version";
|
||||||
|
await exec("node", ["./node_modules/@changesets/cli/bin.js", cmd], { cwd });
|
||||||
|
}
|
||||||
|
|
||||||
|
let searchQuery = `repo:${repo}+state:open+head:${versionBranch}+base:${branch}`;
|
||||||
|
let searchResultPromise = octokit.search.issuesAndPullRequests({
|
||||||
|
q: searchQuery,
|
||||||
|
});
|
||||||
|
let changedPackages = await getChangedPackages(cwd, versionsByDirectory);
|
||||||
|
|
||||||
|
let prBodyPromise = (async () => {
|
||||||
|
return (
|
||||||
|
`This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and ${
|
||||||
|
hasPublishScript
|
||||||
|
? `the packages will be published to npm automatically`
|
||||||
|
: `publish to npm yourself or [setup this action to publish automatically](https://github.com/changesets/action#with-publishing)`
|
||||||
|
}. If you're not ready to do a release yet, that's fine, whenever you add more changesets to ${branch}, this PR will be updated.
|
||||||
|
${
|
||||||
|
!!preState
|
||||||
|
? `
|
||||||
|
⚠️⚠️⚠️⚠️⚠️⚠️
|
||||||
|
|
||||||
|
\`${branch}\` is currently in **pre mode** so this branch has prereleases rather than normal releases. If you want to exit prereleases, run \`changeset pre exit\` on \`${branch}\`.
|
||||||
|
|
||||||
|
⚠️⚠️⚠️⚠️⚠️⚠️
|
||||||
|
`
|
||||||
|
: ""
|
||||||
|
}
|
||||||
|
# Releases
|
||||||
|
` +
|
||||||
|
(
|
||||||
|
await Promise.all(
|
||||||
|
changedPackages.map(async (pkg) => {
|
||||||
|
let changelogContents = await fs.readFile(
|
||||||
|
path.join(pkg.dir, "CHANGELOG.md"),
|
||||||
|
"utf8"
|
||||||
|
);
|
||||||
|
|
||||||
|
let entry = getChangelogEntry(
|
||||||
|
changelogContents,
|
||||||
|
pkg.packageJson.version
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
highestLevel: entry.highestLevel,
|
||||||
|
private: !!pkg.packageJson.private,
|
||||||
|
content:
|
||||||
|
`## ${pkg.packageJson.name}@${pkg.packageJson.version}\n\n` +
|
||||||
|
entry.content,
|
||||||
|
};
|
||||||
|
})
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.filter((x) => x)
|
||||||
|
.sort(sortTheThings)
|
||||||
|
.map((x) => x.content)
|
||||||
|
.join("\n ")
|
||||||
|
);
|
||||||
|
})();
|
||||||
|
|
||||||
|
const finalPrTitle = `${prTitle}${!!preState ? ` (${preState.tag})` : ""}`;
|
||||||
|
const finalCommitMessage = `${commitMessage}${
|
||||||
|
!!preState ? ` (${preState.tag})` : ""
|
||||||
|
}`;
|
||||||
|
|
||||||
|
await gitUtils.commitAll(finalCommitMessage);
|
||||||
|
await gitUtils.push(versionBranch, { force: true });
|
||||||
|
|
||||||
|
let searchResult = await searchResultPromise;
|
||||||
|
console.log(JSON.stringify(searchResult.data, null, 2));
|
||||||
|
if (searchResult.data.items.length === 0) {
|
||||||
|
console.log("creating pull request");
|
||||||
|
await octokit.pulls.create({
|
||||||
|
base: branch,
|
||||||
|
head: versionBranch,
|
||||||
|
title: finalPrTitle,
|
||||||
|
body: await prBodyPromise,
|
||||||
|
...github.context.repo,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
octokit.pulls.update({
|
||||||
|
pull_number: searchResult.data.items[0].number,
|
||||||
|
title: finalPrTitle,
|
||||||
|
body: await prBodyPromise,
|
||||||
|
...github.context.repo,
|
||||||
|
});
|
||||||
|
console.log("pull request found");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,13 +1,4 @@
|
|||||||
import {
|
import { getChangelogEntry, BumpLevels, sortTheThings } from "./utils";
|
||||||
getChangelogEntry,
|
|
||||||
BumpLevels,
|
|
||||||
getChangedPackages,
|
|
||||||
sortTheThings,
|
|
||||||
} from "./utils";
|
|
||||||
import tempy from "tempy";
|
|
||||||
import { exec } from "@actions/exec";
|
|
||||||
import * as fs from "fs-extra";
|
|
||||||
import path from "path";
|
|
||||||
|
|
||||||
let changelog = `# @keystone-alpha/email
|
let changelog = `# @keystone-alpha/email
|
||||||
|
|
||||||
@@ -88,30 +79,6 @@ test("it works", () => {
|
|||||||
expect(entry.highestLevel).toBe(BumpLevels.patch);
|
expect(entry.highestLevel).toBe(BumpLevels.patch);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("getChangedPackages works", async () => {
|
|
||||||
let dir = tempy.directory();
|
|
||||||
await exec("git", ["init"], { cwd: dir });
|
|
||||||
await fs.writeJson(path.join(dir, "package.json"), {
|
|
||||||
name: "some-package",
|
|
||||||
version: "1.0.0",
|
|
||||||
});
|
|
||||||
await fs.writeFile(path.join(dir, "CHANGELOG.md"), "some content");
|
|
||||||
await exec("git", ["add", "."], { cwd: dir });
|
|
||||||
await exec("git", ["commit", "-m", "initial commit"], { cwd: dir });
|
|
||||||
let emptyWorkspaces = await getChangedPackages(dir);
|
|
||||||
expect(emptyWorkspaces).toEqual([]);
|
|
||||||
let workspace = {
|
|
||||||
name: "some-package",
|
|
||||||
version: "2.0.0",
|
|
||||||
};
|
|
||||||
await fs.writeFile(path.join(dir, "CHANGELOG.md"), "other content");
|
|
||||||
await fs.writeJson(path.join(dir, "package.json"), workspace);
|
|
||||||
let workspaces = await getChangedPackages(dir);
|
|
||||||
expect(workspaces).toEqual([
|
|
||||||
{ name: "some-package", dir, config: workspace },
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("it sorts the things right", () => {
|
test("it sorts the things right", () => {
|
||||||
let things = [
|
let things = [
|
||||||
{
|
{
|
||||||
+13
-11
@@ -5,7 +5,6 @@ import remarkStringify from "remark-stringify";
|
|||||||
import mdastToString from "mdast-util-to-string";
|
import mdastToString from "mdast-util-to-string";
|
||||||
import { exec } from "@actions/exec";
|
import { exec } from "@actions/exec";
|
||||||
import { getPackages, Package } from "@manypkg/get-packages";
|
import { getPackages, Package } from "@manypkg/get-packages";
|
||||||
import path from "path";
|
|
||||||
|
|
||||||
export const BumpLevels = {
|
export const BumpLevels = {
|
||||||
dep: 0,
|
dep: 0,
|
||||||
@@ -14,19 +13,22 @@ export const BumpLevels = {
|
|||||||
major: 3,
|
major: 3,
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export async function getChangedPackages(cwd: string) {
|
export async function getVersionsByDirectory(cwd: string) {
|
||||||
let { packages } = await getPackages(cwd);
|
let { packages } = await getPackages(cwd);
|
||||||
let packagesByDirectory = new Map(packages.map((x) => [x.dir, x]));
|
return new Map(packages.map((x) => [x.dir, x.packageJson.version]));
|
||||||
|
}
|
||||||
|
|
||||||
let output = await execWithOutput("git", ["diff", "--name-only"], { cwd });
|
export async function getChangedPackages(
|
||||||
let names = output.stdout.split("\n");
|
cwd: string,
|
||||||
|
previousVersions: Map<string, string>
|
||||||
|
) {
|
||||||
|
let { packages } = await getPackages(cwd);
|
||||||
let changedPackages = new Set<Package>();
|
let changedPackages = new Set<Package>();
|
||||||
for (let name of names) {
|
|
||||||
if (name === "") continue;
|
for (let pkg of packages) {
|
||||||
let dirname = path.resolve(cwd, path.dirname(name));
|
const previousVersion = previousVersions.get(pkg.dir);
|
||||||
let workspace = packagesByDirectory.get(dirname);
|
if (previousVersion !== pkg.packageJson.version) {
|
||||||
if (workspace !== undefined) {
|
changedPackages.add(pkg);
|
||||||
changedPackages.add(workspace);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Vendored
+17
@@ -0,0 +1,17 @@
|
|||||||
|
type Opts = {
|
||||||
|
glob?: string | Array<string>;
|
||||||
|
root?: string;
|
||||||
|
cleanup?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
declare module "fixturez" {
|
||||||
|
export default function (
|
||||||
|
cwd: string,
|
||||||
|
opts?: Opts
|
||||||
|
): {
|
||||||
|
find: (a: string) => string;
|
||||||
|
temp: () => string;
|
||||||
|
copy: (a: string) => string;
|
||||||
|
cleanup: () => any;
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user