-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #10 from waoai/releasetest/various-fixes
Various Improvements
- Loading branch information
Showing
6 changed files
with
976 additions
and
80 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,12 @@ | ||
module.exports = { | ||
env: { | ||
node: true, | ||
commonjs: true, | ||
es2020: true, | ||
}, | ||
extends: "eslint:recommended", | ||
parserOptions: { | ||
ecmaVersion: 12, | ||
}, | ||
rules: {}, | ||
} |
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 |
---|---|---|
@@ -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) | ||
}) |
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,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}", | ||
}, | ||
], | ||
], | ||
} | ||
` |
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,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() |
Oops, something went wrong.