Skip to content

Commit

Permalink
Merge pull request #10 from waoai/releasetest/various-fixes
Browse files Browse the repository at this point in the history
Various Improvements
  • Loading branch information
mrdadah committed Sep 24, 2020
2 parents b264d37 + 99d0b3c commit 58d74a5
Show file tree
Hide file tree
Showing 6 changed files with 976 additions and 80 deletions.
12 changes: 12 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module.exports = {
env: {
node: true,
commonjs: true,
es2020: true,
},
extends: "eslint:recommended",
parserOptions: {
ecmaVersion: 12,
},
rules: {},
}
230 changes: 152 additions & 78 deletions bin/index.js
Original file line number Diff line number Diff line change
@@ -1,97 +1,171 @@
#!/usr/bin/env node

const chalk = require("chalk");
const boxen = require("boxen");
const chalk = require("chalk")
const boxen = require("boxen")
const Confirm = require("prompt-confirm")
const opn = require("opn")
const getReleaseYml = require("../src/get-release-yml.js")
const getReleaseRc = require("../src/get-release-rc.js")

const greeting = chalk.white.bold(`automatic-npm-release
version: 1.0.0`);
version: ${require("../package.json").version}`)

const boxenOptions = {
padding: 1,
margin: 1,
borderStyle: "round",
borderColor: "green"
};
const msgBox = boxen(greeting, boxenOptions);
console.log(msgBox);

const path = require('path');
const fs = require('fs');
const {exec} = require('child_process');
padding: 1,
margin: 1,
borderStyle: "round",
borderColor: "green",
}
boxen(greeting, boxenOptions)

const path = require("path")
const fs = require("fs")
const { spawnSync } = require("child_process")

const destinationPath = process.cwd()

const installSemanticRelease = () => {
return new Promise((resolve, reject) => {
console.log(chalk`Installing {blue.bold @semantic-release/git} ...`);
exec('yarn add --dev @semantic-release/git', {cwd: destinationPath}, (err, stdout, stderr) => {
if (err) {
console.log('Error installing @semantic-release/git')
console.log(chalk`Error installing {red.bold @semantic-release/git}`);
console.error(err);
return reject(err)
}
console.log(chalk`{green.bold @semantic-release/git} installed !`);
console.log()
return resolve()
})
})
return new Promise((resolve, reject) => {
console.log(chalk`Installing {blue.bold @semantic-release/git} ...`)
try {
let spawnArgs
if (fs.existsSync(path.resolve(destinationPath, "yarn.lock"))) {
spawnArgs = ["yarn", ["add", "--dev", "@semantic-release/git"]]
} else {
spawnArgs = ["npm", ["install", "--save-dev", "@semantic-release/git"]]
}
spawnSync(...spawnArgs, {
cwd: destinationPath,
stdio: "inherit",
shell: true,
})
} catch (err) {
console.log("Error installing @semantic-release/git")
console.log(chalk`Error installing {red.bold @semantic-release/git}`)
console.error(err)
return reject(err)
}
console.log(chalk`{green.bold @semantic-release/git} installed !`)
console.log()
return resolve()
})
}

const installReleaseRc = (destinationPath) => {
return new Promise((resolve, reject) => {
console.log(chalk`Creating {blue.bold .releaserc.js} file ...`)
const destinationReleasercPath = path.join(destinationPath, "/releaserc.js")
const content = getReleaseRc()
try {
fs.writeFileSync(destinationReleasercPath, content)
} catch (e) {
console.log(chalk`Error creating {red.bold .releaserc.js} file !`)
reject(e)
}
console.log(chalk`{green.bold .releaserc.js} file created !`)
resolve()
})
}

const copyReleaseRc = (destinationPath) => {
return new Promise((resolve, reject) => {
console.log(chalk`Creating {blue.bold .releaserc.js} file ...`)
const destinationReleasercPath = path.join(destinationPath, '/releaserc.js');
const sourceReleasercPath = path.join(path.dirname(fs.realpathSync(__filename)), '../.releaserc.js');
fs.copyFile(sourceReleasercPath, destinationReleasercPath, (err) => {
if (err) {
console.log(chalk`Error creating {red.bold .releaserc.js} file !`)
return reject(err)
}
console.log(chalk`{green.bold .releaserc.js} file created !`)
console.log()
return resolve()
});
const installReleaseYML = (destinationPath) => {
return new Promise((resolve, reject) => {
let packageJSON
try {
packageJSON = JSON.parse(
fs.readFileSync(path.join(destinationPath, "package.json"))
)
} catch (e) {
return reject(e)
}
console.log(
chalk`Creating {blue.bold .github/workflows/release.yml} file ...`
)
const destinationReleaseYMLPath = path.join(
destinationPath,
"/.github/workflows/release.yml"
)
const destinationGithubFolder = path.join(destinationPath, "/.github")
const destinationWorkflowsFolder = path.join(
destinationPath,
"/.github/workflows"
)

const sourceReleaseYML = getReleaseYml({
testsOn: Boolean(packageJSON.scripts.test),
buildsOn: Boolean(packageJSON.scripts.build),
})

if (!fs.existsSync(destinationGithubFolder)) {
fs.mkdirSync(destinationGithubFolder)
}

if (!fs.existsSync(destinationWorkflowsFolder)) {
fs.mkdirSync(destinationWorkflowsFolder)
}

fs.writeFileSync(destinationReleaseYMLPath, sourceReleaseYML)

console.log(
chalk`{green.bold .github/workflows/release.yml} file created !`
)

return resolve()
})
}

const copyReleaseYML = (destinationPath) => {
return new Promise((resolve, reject) => {
console.log(chalk`Creating {blue.bold .github/workflows/release.yml} file ...`)
const destinationReleaseYMLPath = path.join(destinationPath, '/.github/workflows/release.yml');
const destinationGithubFolder = path.join(destinationPath, '/.github')
const destinationWorkflowsFolder = path.join(destinationPath, '/.github/workflows')
const sourceReleaseYMLPath = path.join(path.dirname(fs.realpathSync(__filename)), '../.github/workflows/release.yml');

if (!fs.existsSync(destinationGithubFolder)) {
fs.mkdirSync(destinationGithubFolder);
}

if (!fs.existsSync(destinationWorkflowsFolder)) {
fs.mkdirSync(destinationWorkflowsFolder);
}

fs.copyFile(sourceReleaseYMLPath, destinationReleaseYMLPath, (err) => {
if (err) {
console.log(chalk`Error creating {red.bold .github/workflows/release.yml} file !`)
return reject(err)
}
console.log(chalk`{green.bold .github/workflows/release.yml} file created !`)
console.log()
return resolve()
});
const generateNPMToken = async () => {
if (
await new Confirm(
"Do you want to generate an npm token now? (using `npm token create`) You'll need to add a token to Github"
).run()
) {
spawnSync("npm", ["token", "create"], {
stdio: "inherit",
shell: true,
})
}
}

const openGithubSecretsPage = async () => {
const packageJSON = JSON.parse(
fs.readFileSync(path.resolve(destinationPath, "package.json"))
)
if (!packageJSON.repository) return
const repoUrl =
typeof packageJSON.repository === "string"
? packageJSON.repository
: packageJSON.repository.url

let repo
if (repoUrl.includes("github.com")) {
repo = repoUrl.match(/github.com\/([a-zA-Z0-9-]+\/[a-zA-Z0-9-]+)/)[1]
} else if (repoUrl.includes("github:")) {
repo = repoUrl.match(/github:([a-zA-Z0-9/-]+)/)[1]
}
if (repo && (await new Confirm("Open your github secrets page?").run())) {
opn(`https://github.com/${repo}/settings/secrets/new`)
}
}

async function main() {
await installSemanticRelease(destinationPath)
await installReleaseYML(destinationPath)
await installReleaseRc(destinationPath)
await generateNPMToken().catch((e) => {
console.log(e.toString())
})
await openGithubSecretsPage().catch((e) => {
console.log(e.toString())
})
console.log(chalk`After merging this, your merges to master will automatically be published.
Make sure to use the semantic versioning system in your commits.
e.g. start a commit with "fix: ..."`)
console.log(
chalk`Make sure to set {bold NPM_TOKEN} in your github repository secrets !`
)
}

installSemanticRelease().then(() => {
return copyReleaseRc(destinationPath)
}).then(() => {
return copyReleaseYML(destinationPath)
}).then(() => {
console.log(chalk`Make sure to set {bold NPM_TOKEN} in your github repository secrets !`)
console.log(chalk`After merging this, your merges to master will automatically be published.
Make sure to use the semantic versioning system in your commits.
e.g. start a commit with "fix: ..."`)
}, (err) => {
console.log(err)
main().catch((e) => {
console.log(`Installation failed with error: ${e.toString()}`)
process.exit(1)
})
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,12 @@
"homepage": "https://github.com/waoai/automatic-npm-release#readme",
"dependencies": {
"boxen": "^4.0.0",
"chalk": "^2.4.2"
"chalk": "^2.4.2",
"opn": "^6.0.0",
"prompt-confirm": "^2.0.4"
},
"devDependencies": {
"@semantic-release/git": "^9.0.0"
"@semantic-release/git": "^9.0.0",
"eslint": "^7.9.0"
}
}
18 changes: 18 additions & 0 deletions src/get-release-rc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module.exports = () => `module.exports = {
branch: "master",
plugins: [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
["@semantic-release/npm", { npmPublish: true }],
"@semantic-release/github",
[
"@semantic-release/git",
{
assets: ["package.json"],
message:
"chore(release): \${nextRelease.version} [skip ci]\n\n\${nextRelease.notes}",
},
],
],
}
`
40 changes: 40 additions & 0 deletions src/get-release-yml.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
module.exports = ({ testsOn = false, buildsOn = false } = {}) =>
`
name: Release
on:
push:
branches:
- master
- "releasetest/**"
jobs:
release:
if: "!contains(github.event.head_commit.message, 'skip ci')"
name: Release
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Setup Node.js
uses: actions/setup-node@v1
with:
node-version: 12
- name: Install dependencies
run: npm install${
buildsOn
? `\n
- name: Build
run: npm run build`
: ""
}${
testsOn
? `\n
- name: Run Tests
run: npm run test`
: ""
}
- name: Release
env:
GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: \${{ secrets.NPM_TOKEN }}
run: npx semantic-release
`.trim()
Loading

0 comments on commit 58d74a5

Please sign in to comment.