Skip to content

Commit

Permalink
3.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
MoOx committed Jan 20, 2016
1 parent 993d8ae commit d8e09b7
Show file tree
Hide file tree
Showing 7 changed files with 333 additions and 62 deletions.
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
# 3.0.0 - 2016-01-20

**Complete rewrite using Node.js instead of sh.**

- Changed: bin is now "npmpub"
- Added: Does a GitHub release by default from the version number and the
corresponding section in your changelog.
- Added: ``--help`` to see the help
- Added: ``--verbose`` to see some informations.
- Added: ``--debug`` to see all informations about process.
- Added: ``--skip-status`` to skip git status check
- Added: ``--skip-fetch`` to skip git fetch to compare remote
- Added: ``--skip-compare`` to skip git comparison with origin
- Added: ``--skip-cleanup`` to skip node_modules cleanup
- Added: ``--dry`` to skip npm publish, just to check that tests are ok.
- Added: ``--no-release`` to avoid the GitHub release from changelog.

# 2.0.0 - 2016-01-11

- Changed: do not rebase by default, but instead show a warning if relevant.
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) Maxime Thirouin, Sindre Sorhus
Copyright (c) Maxime Thirouin

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
Expand Down
100 changes: 80 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,97 @@
# npmpub(lish)
# npmpub

> Another better `npm publish`
> `npm publish` on steroid
**Works great with [github-release-from-changelog](https://github.com/MoOx/github-release-from-changelog).**
## What is this?

## Why
The ``npm publish`` command is nice, but you always have to handle things before
(fresh tests) and after (tag, GitHub release)... So if you want to release
faster, just use this package/command!

- Pulls in remote git commits to ensure you publish the latest commit
- Reinstalls dependencies to ensure your project works with the latest dependency tree
- Runs the tests
- Bumps the version from the one in package.json and creates a git tag
- Publishes the new version to npm
- Pushes commits and tags to GitHub
- Pulls in remote git commits to ensure you publish the latest commit.
- Checks that a tag does not exist with the current version.
- Reinstalls dependencies to ensure your project works with a fresh dependency
tree.
- Runs the tests.
- Publishes a new version to npm.
- Creates a git tag.
- Pushes commits and tags to GitHub.
- Edits the tag as a GitHub release based on the new version and corresponding
changelog version.

### What is the difference with `np`?
## Install

This `npmpublish` takes the version from the `package.json`.
I was using the orignal `np` recipe, but I discovered that I was already always
updating the version in the `CHANGELOG.md` by hand, so why not directly
specifying the version everywhere in the same commit?
```
$ npm install -D npmpub
```

## Install
## Usage

Since you are probably
[maintaining a CHANGELOG (or you should)](http://keepachangelog.com/), you
already handle by hand version number (because you care about
[semver](http://semver.org/), don't you?).

So here is how to use this command:

- Prepare your ``CHANGELOG``. The best (and easy way) to do this is by
preparing your changelog while you commit your features/fixes.
It make the release process more easy.
So when you commit an API change, a feature or a fix, add your commit message
in your CHANGELOG prefixed by _Removed/Changed/Added/Fixed_.
- Update your version number in your ``CHANGELOG``.
It's very easy to choose a version number:
- If you have at least a _Removed_ or a _Changed_, it's a **breaking change**,
so increment the first number (X.y.z),
- If you have _Added_ something, it's a **minor change**,
so increment the second number (x.Y.z),
- If you just have _Fixed_ something, it's a **patch**,
so increment the last number (x.y.Z).
- Update your version number in your ``package.json``
- Commit
- Run `npmpub` so have a clean release (fresh tests + tag + GitHub release
notes)

## How to run `npmpub`?

There is two way:

```console
$ ./node_modules/.bin/npmpub
```
$ npm install --global npmpub

Or you can add a npm scripts in your ``package.json``

```json
{
"scripts": {
"release": "npmpub"
}
}
```

**Note that the package is `npmpub` and the command is `npmpublish`.**
This way you can run

## Usage
```console
$ npm run release
```

## Options

```console
$ npmpublish
$ ./node_modules/.bin/npmpub --help

npmpub [options]

--help Just what you are reading.
--verbose Get some informations.
--debug Get all informations about process.
--skip-status Skip git status check (⚠︎ you might release unversionned stuff).
--skip-fetch Skip git fetch to compare remote (⚠︎ you might not be able to push).
--skip-compare Skip git comparison with origin (⚠︎ you might not be able to push).
--skip-cleanup Skip node_modules cleanup (⚠︎ you might miss some dependencies changes).
--dry No publish, just check that tests are ok.
--no-release No GitHub release from changelog.
```

---
Expand Down
199 changes: 199 additions & 0 deletions npmpub.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
#!/usr/bin/env node

"use strict"

const path = require("path")

const colors = require("chalk")
const sh = require("shelljs")
const exec = sh.exec
const exit = sh.exit
const parseArgs = require("minimist")
const trash = require("trash")

const argv = parseArgs(process.argv.slice(2), { boolean: true })

const print = (msg) => console.log("📦 " + msg)
const notice = (msg) => print(colors.yellow.bold(msg))
const log = (msg) => argv.verbose && print(colors.yellow(msg))
const debug = (msg) => argv.debug && print(msg)
const error = (msg) => print(colors.red.bold(msg))

const cmds = {
gitStatus: "git status --porcelain",
gitFetch: "git fetch --quiet",
gitCheckRemote: "git rev-list --count --left-only @'{u}'...HEAD",
}

if (argv["help"]) {
/* eslint-disable max-len */
console.log(`npmpub [options]
--help Just what you are reading.
--verbose Get some informations.
--debug Get all informations about process.
--skip-status Skip git status check (⚠︎ you might release unversionned stuff).
--skip-fetch Skip git fetch to compare remote (⚠︎ you might not be able to push).
--skip-compare Skip git comparison with origin (⚠︎ you might not be able to push).
--skip-cleanup Skip node_modules cleanup (⚠︎ you might miss some dependencies changes).
--dry No publish, just check that tests are ok.
--no-release No GitHub release from changelog.
`)
/* eslint-enable max-len */
exit(0)
}

const execOpts = { silent: !argv.debug }

// check clean status
if (argv["skip-status"]) {
log("Git status check skipped.")
}
else {
debug(cmds.gitStatus)
const gitStatus = exec(cmds.gitStatus, execOpts)
if (gitStatus.code !== 0 || gitStatus.output !== "") {
error("Unclean working tree. Commit or stash changes first.")
exit(1)
}
else {
log("Git working directory clean.")
}
}

// fetch remote
if (argv["skip-fetch"]) {
log("Git fetch skipped.")
}
else {
debug(cmds.gitFetch)
const gitFetch = exec(cmds.gitFetch, execOpts)
if (gitFetch.code !== 0) {
error("There was a problem fetching your branch.")
exit(1)
}
else {
log("Git fetch done.")
}
}

// compare remote
if (argv["skip-compare"]) {
log("Git comparison skipped.")
}
else {
debug(cmds.gitCheckRemote)
const gitCheckRemote = exec(cmds.gitCheckRemote, execOpts)
if (gitCheckRemote.output !== "0\n") {
error("Remote history differ. Please pull changes.")
exit(1)
}
else {
log("Git local copy up to date.")
}
}

const pkg = path.join(process.cwd(), "package.json")
log("package.json is '" + pkg + "'.")
const version = require(pkg).version
notice("Preparing v" + version + ".")

log("Checking existing tags.")
const gitTags = exec("git tag", { silent: true })
if (gitTags.code !== 0) {
error("Can't read tags.")
exit(1)
}
else if (gitTags.output.split("\n").indexOf(version) > -1) {
error("Tag already exist.")
exit(1)
}

let cleanupPromise
if (argv["skip-cleanup"]) {
log("Cleanup skipped.")
cleanupPromise = Promise.resolve()
}
else {
log("Cleaning node_modules.")
const nodeModules = path.join(process.cwd(), "node_modules")
if (argv.verbose) {
debug("Will delete '" + nodeModules + "'.")
}
cleanupPromise = trash([ nodeModules ])
.then(() => {
log("node_modules deleted.")
notice("Running 'npm install'. This can take a while.")
return new Promise((resolve) => {
exec("npm install", execOpts, (code, stdout, stderr) => {
if (code === 0) {
resolve()
}
else {
console.log(stderr)
error("npm install failed.")
exit(1)
}
})
})
})
}

cleanupPromise
.then(() => {
notice("Running tests...")
const npmTest = exec("npm test")
if (npmTest.code !== 0) {
throw new Error("'npm test' failed.")
}

if (argv.dry) {
notice("Dry run. No publish.")
}
else {
notice("Publishing...")
const npmPublish = exec("npmPublish " + version)
if (npmPublish.code !== 0) {
error("Publishing failed.")
exit(1)
}

log("Tagging.")
const gitTag = exec("git tag " + version)
if (gitTag.code !== 0) {
error("Tagging failed.")
exit(1)
}

log("Git push.")
const gitPush = exec("git push --follow-tags")
if (gitPush.code !== 0) {
error("pushing failed.")
exit(1)
}

if (argv["no-release"]) {
log("No GitHub release.")
}
else {
log("GitHub release.")
const githubRelease = exec(
"./node_modules/.bin/github-release-from-changelog"
)
if (githubRelease.code !== 0) {
error("GitHub release failed.")
exit(1)
}
}
}
})
.catch((err) => {
if (err) {
setTimeout(() => {
throw err
}, 1)
}
else {
exit(1)
}
})
34 changes: 0 additions & 34 deletions npmpublish.sh

This file was deleted.

Loading

1 comment on commit d8e09b7

@jeddy3
Copy link

@jeddy3 jeddy3 commented on d8e09b7 Jan 22, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow. Looks fab!

Just ran this version to release stylelint 4.1.0, and all went well.

Thanks for doing this rewrite, it makes releasing effortless :)

Please sign in to comment.