Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ Set of [semantic-release](https://github.com/semantic-release/semantic-release)
{
"release": {
"verifyConditions": "semantic-release-docker",
"prepare": "semantic-release-docker",
"publish": {
"path": "semantic-release-docker",
"name": "username/imagename"
"name": "username/imagename",
"buildCmd": "docker build -t username/imagename .
}
}
}
Expand All @@ -29,14 +31,23 @@ Set of [semantic-release](https://github.com/semantic-release/semantic-release)

Your credentials have to be configured with the environment variables `DOCKER_USERNAME` and `DOCKER_PASSWORD`.

In addition, you need to specify the name of the image as the `name` setting.
In addition, you need to specify
* the name of the image as the `name` setting
* your Docker build command as `buildCmd`

Optionally
* your package root as `pkgRoot` - make sure you have the correct path in your build command, too.

## Plugins

### `verifyConditions`

Verify that all needed configuration is present and login to the Docker registry.

### `prepare`

Update `package.json` version, and build Docker image.

### `publish`

Tag the image specified by `name` with the new version, push it to Docker Hub and update the `latest` tag.
Expand All @@ -52,7 +63,6 @@ jobs:
services:
- docker
script:
- docker build -t username/imagename .
- npm run semantic-release

stages:
Expand Down
2 changes: 2 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
const verifyConditions = require('./lib/verify')
const publish = require('./lib/publish')
const prepare = require('./lib/prepare')

module.exports = {
verifyConditions,
prepare,
publish,
}
16 changes: 16 additions & 0 deletions lib/prepare.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
Blatantly copied from semantic-release/npm by Pierre Vanduynslager (https://twitter.com/@pvdlg_)
https://github.com/semantic-release/npm
*/

const execa = require('execa')
const updatePackageVersion = require('./update-package-version')

module.exports = async ({ name, buildCmd, pkgRoot }, version, logger) => {
const basePath = pkgRoot || '.'
await updatePackageVersion(version, basePath, logger)
Copy link
Owner

Choose a reason for hiding this comment

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

what is the purpose of updating the package.json version? What if there is no package.json because it's not an npm package?


logger.log(`Building ${name} Docker image using command: ${buildCmd}`)

execa(`${buildCmd}`, { stdio: 'inherit' })
Copy link
Owner

Choose a reason for hiding this comment

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

It seems like this step could just be @semantic-release/exec?

}
39 changes: 39 additions & 0 deletions lib/update-package-version.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
Blatantly copied from semantic-release/npm by Pierre Vanduynslager (https://twitter.com/@pvdlg_)
https://github.com/semantic-release/npm
*/

const path = require('path')
const parseJson = require('parse-json')
const detectIndent = require('detect-indent')
const detectNewline = require('detect-newline')
const { readFile, writeJson, pathExists } = require('fs-extra')

const DEFAULT_INDENT = 2
const DEFAULT_NEWLINE = '\n'

module.exports = async (version, basePath, logger) => {
const packagePath = path.join(basePath, 'package.json')
const shrinkwrapPath = path.join(basePath, 'npm-shrinkwrap.json')
const packageLockPath = path.join(basePath, 'package-lock.json')
const pkg = await readFile(packagePath, 'utf8')

await writeJson(packagePath, { ...parseJson(pkg), ...{ version } }, getWriteOptions(pkg))
logger.log('Wrote version %s to %s', version, packagePath)

if (await pathExists(shrinkwrapPath)) {
const shrinkwrap = await readFile(shrinkwrapPath, 'utf8')
await writeJson(shrinkwrapPath, { ...parseJson(shrinkwrap), ...{ version } }, getWriteOptions(shrinkwrap))
logger.log('Wrote version %s to %s', version, shrinkwrapPath)
}

if (await pathExists(packageLockPath)) {
const packageLock = await readFile(packageLockPath, 'utf8')
await writeJson(packageLockPath, { ...parseJson(packageLock), ...{ version } }, getWriteOptions(packageLock))
logger.log('Wrote version %s to %s', version, packageLockPath)
}
}

function getWriteOptions(content) {
return { spaces: detectIndent(content).indent || DEFAULT_INDENT, EOL: detectNewline(content) || DEFAULT_NEWLINE }
}
8 changes: 7 additions & 1 deletion lib/verify.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
const execa = require('execa')

module.exports = async (pluginConfig, { logger }) => {
module.exports = async ({ buildCmd, name }, { logger }) => {
for (const envVar of ['DOCKER_USERNAME', 'DOCKER_PASSWORD']) {
if (!process.env[envVar]) {
throw new Error(`Environment variable ${envVar} is not set`)
}
}
if (!buildCmd) {
throw new Error(`Docker build command (buildCmd) is not set`)
}
if (!name) {
throw new Error(`Docker image name (name) is not set`)
}
try {
await execa('docker', ['login', '-u=' + process.env.DOCKER_USERNAME, '-p=' + process.env.DOCKER_PASSWORD], {
stdio: 'inherit',
Expand Down
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@
},
"dependencies": {
"@semantic-release/error": "^2.1.0",
"execa": "^0.10.0"
"detect-indent": "^5.0.0",
"detect-newline": "^2.1.0",
"execa": "^0.10.0",
"fs-extra": "^6.0.1",
"parse-json": "^4.0.0"
},
"devDependencies": {
"cz-conventional-changelog": "^2.0.0",
Expand Down