Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Automatic Canary Releases for PRs (#141)
- Loading branch information
1 parent
4b19e05
commit 0ec01d2
Showing
3 changed files
with
135 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
name: Canary Release | ||
|
||
on: | ||
pull_request: | ||
branches: | ||
- master | ||
|
||
jobs: | ||
publish-canary: | ||
name: Publish Canary | ||
runs-on: ubuntu-latest | ||
if: github.event.pull_request.head.repo.full_name == github.repository | ||
steps: | ||
- name: Checkout master | ||
uses: actions/checkout@v2 | ||
with: | ||
fetch-depth: 0 | ||
- name: Use Node | ||
uses: actions/setup-node@v2 | ||
with: | ||
node-version: '16.x' | ||
- uses: bahmutov/npm-install@v1 | ||
- name: Setup NPM credentials | ||
run: echo "//registry.npmjs.org/:_authToken=$NODE_AUTH_TOKEN" >> ~/.npmrc | ||
env: | ||
NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }} | ||
- name: Release Canary | ||
id: canary | ||
uses: 'kamilkisiela/release-canary@master' | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
NPM_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }} | ||
with: | ||
npm-token: ${{ secrets.NODE_AUTH_TOKEN }} | ||
npm-script: 'yarn release:canary' | ||
changesets: true | ||
- name: Publish a message | ||
if: steps.canary.outputs.released == 'true' | ||
uses: 'kamilkisiela/pr-comment@master' | ||
with: | ||
commentKey: canary | ||
message: | | ||
The latest changes of this PR are available as canary in npm (based on the declared `changesets`): | ||
``` | ||
${{ steps.canary.outputs.changesetsPublishedPackages}} | ||
``` | ||
bot-token: ${{ secrets.GITHUB_TOKEN }} | ||
bot: 'github-actions[bot]' | ||
github-token: ${{ secrets.GITHUB_TOKEN }} | ||
- name: Publish a empty message | ||
if: steps.canary.outputs.released == 'false' | ||
uses: 'kamilkisiela/pr-comment@master' | ||
with: | ||
commentKey: canary | ||
message: | | ||
The latest changes of this PR are not available as canary, since there are no linked `changesets` for this PR. | ||
bot-token: ${{ secrets.GITHUB_TOKEN }} | ||
bot: 'github-actions[bot]' | ||
github-token: ${{ secrets.GITHUB_TOKEN }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
/* eslint-disable */ | ||
const semver = require("semver"); | ||
const cp = require("child_process"); | ||
const { basename } = require("path"); | ||
|
||
const { read: readConfig } = require("@changesets/config"); | ||
const readChangesets = require("@changesets/read").default; | ||
const assembleReleasePlan = require("@changesets/assemble-release-plan").default; | ||
const applyReleasePlan = require("@changesets/apply-release-plan").default; | ||
const { getPackages } = require("@manypkg/get-packages"); | ||
|
||
function getNewVersion(version, type) { | ||
const gitHash = cp.spawnSync("git", ["rev-parse", "--short", "HEAD"]).stdout.toString().trim(); | ||
|
||
return semver.inc(version, `pre${type}`, true, "canary-" + gitHash); | ||
} | ||
|
||
function getRelevantChangesets(baseBranch) { | ||
const comparePoint = cp | ||
.spawnSync("git", ["merge-base", `origin/${baseBranch}`, "HEAD"]) | ||
.stdout.toString() | ||
.trim(); | ||
const listModifiedFiles = cp.spawnSync("git", ["diff", "--name-only", comparePoint]).stdout.toString().trim().split("\n"); | ||
|
||
const items = listModifiedFiles.filter((f) => f.startsWith(".changeset")).map((f) => basename(f, ".md")); | ||
|
||
return items; | ||
} | ||
|
||
async function updateVersions() { | ||
const cwd = process.cwd(); | ||
const packages = await getPackages(cwd); | ||
const config = await readConfig(cwd, packages); | ||
const modifiedChangesets = getRelevantChangesets(config.baseBranch); | ||
const changesets = (await readChangesets(cwd)).filter((change) => modifiedChangesets.includes(change.id)); | ||
|
||
if (changesets.length === 0) { | ||
console.warn(`Unable to find any relevant package for canary publishing. Please make sure changesets exists!`); | ||
process.exit(1); | ||
} else { | ||
const releasePlan = assembleReleasePlan(changesets, packages, config, [], false); | ||
|
||
if (releasePlan.releases.length === 0) { | ||
console.warn(`Unable to find any relevant package for canary releasing. Please make sure changesets exists!`); | ||
process.exit(1); | ||
} else { | ||
for (const release of releasePlan.releases) { | ||
if (release.type !== "none") { | ||
release.newVersion = getNewVersion(release.oldVersion, release.type); | ||
} | ||
} | ||
|
||
await applyReleasePlan( | ||
releasePlan, | ||
packages, | ||
{ | ||
...config, | ||
commit: false, | ||
}, | ||
false, | ||
true | ||
); | ||
} | ||
} | ||
} | ||
|
||
updateVersions() | ||
.then(() => { | ||
console.info(`Done!`); | ||
}) | ||
.catch((err) => { | ||
console.error(err); | ||
process.exit(1); | ||
}); |