Skip to content

Commit

Permalink
Merge pull request #804 from dynamoosejs/publishAutomation
Browse files Browse the repository at this point in the history
Publish Automation
  • Loading branch information
fishcharlie committed Apr 16, 2020
2 parents 17cd52f + 4b09881 commit d5f2833
Show file tree
Hide file tree
Showing 8 changed files with 1,588 additions and 13 deletions.
45 changes: 45 additions & 0 deletions .github/workflows/publish.yml
@@ -0,0 +1,45 @@
name: Publish

on:
release:
types: [created]

jobs:
getinfo:
runs-on: ubuntu-latest
outputs:
tag: ${{ steps.data.outputs.tag }}
steps:
- uses: actions/checkout@v2
- run: node publish/information.js
id: data

publish-npm:
needs: get-info
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: 12
registry-url: https://registry.npmjs.org/
- run: npm ci
- run: npm publish --tag $TAG
env:
TAG: ${{ needs.getinfo.outputs.tag }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

publish-gpr:
needs: get-info
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: 12
registry-url: https://npm.pkg.github.com/
- run: npm ci
- run: npm publish --tag $TAG
env:
TAG: ${{ needs.getinfo.outputs.tag }}
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
3 changes: 2 additions & 1 deletion .nycrc
Expand Up @@ -3,6 +3,7 @@
"test",
"coverage",
".eslintrc.js",
".mocharc.js"
".mocharc.js",
"publish"
]
}
12 changes: 0 additions & 12 deletions CHANGELOG.md
Expand Up @@ -2,18 +2,6 @@

---

## Version 2.0.0 (Not Complete)

This is the working changelog for version 2.0.0. It is a full rewrite of Dynamoose from the ground up. It is very likely throughout this beta that breaking changes will occur.

Please comment or [contact me](https://charlie.fish/contact) if you have any questions about this release.

### General

- License changed from MIT to Unlicense

---

## [1.11.1](https://github.com/dynamoosejs/dynamoose/compare/v1.11.0...v1.11.1) (2019-09-05)


Expand Down
179 changes: 179 additions & 0 deletions publish/index.js
@@ -0,0 +1,179 @@
const inquirer = require("inquirer");
const fs = require("fs").promises;
const git = require("simple-git/promise")();
const openurl = require("openurl");
const utils = require("../lib/utils");
const util = require("util");
const exec = util.promisify(require("child_process").exec);
const retrieveInformation = require("./information/retrieve");
const { Octokit } = require("@octokit/rest");
const octokit = new Octokit({
"log": console,
"auth": process.env.GITHUBAUTH
});
const ora = require("ora");
const npmFetch = require("npm-registry-fetch");
let package = require("../package.json");

(async function main() {
console.log("Welcome to the Dynamoose Publisher!\n\n\n");
if (!await checkCleanWorkingDir()) {
console.error("You must have a clean working directory in order to use this tool.");
console.error("Exiting.\n");
process.exit(1);
}
let results = await inquirer.prompt([
{
"name": "branch",
"type": "list",
"message": "What branch would you like to publish?",
"choices": (await git.branchLocal()).all,
"default": (await git.status()).current
}
]);
await git.checkout(results.branch);
package = require("../package.json");
results = { // eslint-disable-line require-atomic-updates
...results,
...await inquirer.prompt([
{
"name": "version",
"type": "input",
"message": "What version would you like to publish?",
"default": package.version,
"validate": (val) => val !== package.version ? true : `${val} is the current version in the package.json. Please pick a new version to publish.`
},
{
"name": "isPrerelease",
"type": "confirm",
"message": "Is this version a prerelease version?",
"default": (res) => Boolean(retrieveInformation(res.version).tag)
},
{
"name": "confirm",
"type": "confirm",
"message": "Does all of the information look correct?",
"default": false
}
])
};
process.stdin.resume();
if (!results.confirm) {
console.error("No action has been taken.");
console.error("Exiting.\n");
process.exit(1);
}

// Create new branch
const branch = `version/${results.version}`;
const branchSpinner = ora(`Creating branch ${branch}`).start();
await git.checkoutBranch(branch, results.branch);
branchSpinner.succeed(`Created branch ${branch}`);
// Update version in package.json
const updateVersion = async (file) => {
const path = `../${file}`;
let fileContents = await fs.readFile(path);
const fileContentsJSON = JSON.parse(fileContents);
fileContentsJSON.version = results.version;
fileContents = JSON.stringify(fileContentsJSON, null, 2);
await fs.writeFile(path, `${fileContents}\n`);
};
const packageUpdateVersionsSpinner = ora("Updating versions in package.json & package-lock.json files").start();
await Promise.all(["package.json", "package-lock.json"].map(updateVersion));
packageUpdateVersionsSpinner.succeed("Updated versions in package.json & package-lock.json files");
// Add, Commit & Push files to Git
const gitCommit = ora("Committing files to Git").start();
await git.commit(`Bumping version to ${results.version}`, ["../package.json", "../package-lock.json"]);
gitCommit.succeed("Committed files to Git");
const gitPush = ora("Pushing files to GitHub").start();
await git.push("origin", branch);
gitPush.succeed("Pushed files to GitHub");
// Changelog
console.log("This tool will now open a web browser with a list of commits since the last verison.\nPlease use this information to fill out a change log.\n");
console.log("Press any key to proceed.");
await keypress();
openurl.open(`https://github.com/dynamoosejs/dynamoose/compare/v${package.version}...${results.branch}`);
const versionInfo = retrieveInformation(results.version);
const versionFriendlyTitle = `Version ${[versionInfo.main, utils.capitalize_first_letter(versionInfo.tag || ""), versionInfo.tagNumber].filter((a) => Boolean(a)).join(" ")}`;
await fs.writeFile(`${results.version}-changelog.md`, `## ${versionFriendlyTitle}\n\nThis release ________\n\nPlease comment or [contact me](https://charlie.fish/contact) if you have any questions about this release.\n\n### Major New Features\n\n### General\n\n### Bug Fixes\n\n### Documentation\n\n### Other`);
await exec(`code ${results.version}-changelog.md`);
const pendingChangelogSpinner = ora("Waiting for user to finish changelog, press enter to continue.").start();
await keypress();
pendingChangelogSpinner.succeed("Finished changelog");
const versionChangelog = await fs.readFile(`${results.version}-changelog.md`);
if (!versionInfo.tag) {
const existingChangelog = await fs.readFile("../CHANGELOG.md", "utf8");
const existingChangelogArray = existingChangelog.split("\n---\n");
existingChangelogArray.splice(1, 0, `\n${versionChangelog}\n`);
await fs.writeFile("../CHANGELOG.md", existingChangelogArray.join("\n---\n"));
const gitCommit2 = ora("Committing files to Git").start();
await git.commit(`Adding changelog for ${results.version}`, ["../CHANGELOG.md"]);
gitCommit2.succeed("Committed files to Git");
const gitPush2 = ora("Pushing files to GitHub").start();
await git.push("origin", branch);
gitPush2.succeed("Pushed files to GitHub");
}
// Create PR
const gitPR = ora("Creating PR on GitHub").start();
const pr = (await octokit.pulls.create({"owner": "dynamoosejs", "repo": "dynamoose", "title": versionFriendlyTitle, "head": branch, "base": results.branch})).data;
gitPR.succeed(`Created PR: ${pr.number} on GitHub`);
openurl.open(`https://github.com/dynamoosejs/dynamoose/pull/${pr.number}`);
// Poll for PR to be merged
const gitPRPoll = ora(`Polling GitHub for PR ${pr.number} to be merged`).start();
await isPRMerged(pr.number);
gitPRPoll.succeed(`PR ${pr.number} has been merged`);
console.log("PR has been merged.");
// Create release
const gitRelease = ora("Creating release on GitHub").start();
await octokit.repos.createRelease({
"owner": "dynamoosejs",
"repo": "dynamoose",
"tag_name": `v${results.version}`,
"target_commitish": results.branch,
"name": `v${results.version}`,
"body": versionChangelog,
"prerelease": Boolean(versionInfo.tag)
});
gitRelease.succeed("GitHub release created");
// Poll NPM for release
const npmPoll = ora("Polling NPM for release").start();
await isReleaseSubmiitted(results.version);
npmPoll.succeed("Version successfully published to NPM");
// Complete
process.exit(0);
})();

async function checkCleanWorkingDir() {
return (await git.status()).isClean();
}

function keypress() {
process.stdin.setRawMode(true);
return new Promise((resolve) => {
process.stdin.once("data", () => {
process.stdin.setRawMode(false);
resolve();
process.stdin.pause();
});
});
}

async function isPRMerged(pr) {
let data;
do {
data = (await octokit.pulls.get({
"owner": "dynamoosejs",
"repo": "dynamoose",
"pull_number": pr
})).data;
await utils.timeout(5000);
} while (!data.merged);
}
async function isReleaseSubmiitted(release) {
try {
await npmFetch(`/dynamoose/${release}`);
} catch (e) {
await utils.timeout(5000);
isReleaseSubmiitted(release);
}
}
10 changes: 10 additions & 0 deletions publish/information/index.js
@@ -0,0 +1,10 @@
const core = require("@actions/core");
const package = require("../../package.json");
const version = package.version;
const {main, tag, tagNumber} = require("./retrieve")(version);

core.setOutput("main", main);
core.setOutput("tag", tag);
core.setOutput("tagNumber", tagNumber);

console.log({main, tag, tagNumber});
5 changes: 5 additions & 0 deletions publish/information/retrieve.js
@@ -0,0 +1,5 @@
module.exports = (version) => {
const regex = /^v?((?:\d\.?){1,3})(?:-(.*)\.(\d*))?$/gmu;
const [,main,tag,tagNumber] = regex.exec(version);
return {main, tag, tagNumber};
};

0 comments on commit d5f2833

Please sign in to comment.