diff --git a/README.md b/README.md index bb65e4d..dda6dca 100644 --- a/README.md +++ b/README.md @@ -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 . } } } @@ -29,7 +31,12 @@ 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 @@ -37,6 +44,10 @@ In addition, you need to specify the name of the image as the `name` setting. 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. @@ -52,7 +63,6 @@ jobs: services: - docker script: - - docker build -t username/imagename . - npm run semantic-release stages: diff --git a/index.js b/index.js index 2ba859f..0f8a566 100644 --- a/index.js +++ b/index.js @@ -1,7 +1,9 @@ const verifyConditions = require('./lib/verify') const publish = require('./lib/publish') +const prepare = require('./lib/prepare') module.exports = { verifyConditions, + prepare, publish, } diff --git a/lib/prepare.js b/lib/prepare.js new file mode 100644 index 0000000..2fa5e75 --- /dev/null +++ b/lib/prepare.js @@ -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) + + logger.log(`Building ${name} Docker image using command: ${buildCmd}`) + + execa(`${buildCmd}`, { stdio: 'inherit' }) +} diff --git a/lib/update-package-version.js b/lib/update-package-version.js new file mode 100644 index 0000000..56e8a5c --- /dev/null +++ b/lib/update-package-version.js @@ -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 } +} diff --git a/lib/verify.js b/lib/verify.js index 34e2150..2725c99 100644 --- a/lib/verify.js +++ b/lib/verify.js @@ -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', diff --git a/package.json b/package.json index cfd73fd..86a8de3 100644 --- a/package.json +++ b/package.json @@ -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",