Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
evansiroky committed Jul 19, 2018
2 parents a8a0448 + d57d318 commit 70b3dc6
Show file tree
Hide file tree
Showing 7 changed files with 1,095 additions and 579 deletions.
6 changes: 0 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,6 @@ Your pom.xml file also needs the following sonatype plugin to automatically clos

- `nexus-staging-maven-plugin`

Also, in order to work with this project, your pom.xml file must include a comment next to the version entry. This is so that this tool can make appropriate changes.

```
<version>2.0.1-SNAPSHOT</version> <!-- semantic-release-version-line -->
```

<span style="font-size:larger;">[See this example project for a sample pom.xml](https://github.com/evansiroky/maven-semantic-release-example/blob/master/pom.xml).</span>

### Step 3: Create a maven-settings.xml file
Expand Down
6 changes: 3 additions & 3 deletions bin/release-cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ const semanticRelease = require('semantic-release/cli')
*/
async function run () {
process.argv.push(...[
'--get-last-release',
'@conveyal/maven-semantic-release/lib/get-last-release',
'--publish',
'@conveyal/maven-semantic-release/lib/publish',
'--verify-conditions',
'@semantic-release/github,@semantic-release/condition-travis'
'@semantic-release/github',
'--verify-release',
'@conveyal/maven-semantic-release/lib/verify-release'
])

await semanticRelease()
Expand Down
69 changes: 0 additions & 69 deletions lib/get-last-release.js

This file was deleted.

58 changes: 21 additions & 37 deletions lib/publish.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
const debug = require('debug')('maven-semantic-release:publish')
const execa = require('execa')
const fs = require('fs-extra')
const semanticGithub = require('@semantic-release/github')
const {gitHead: getGitHead} = require('semantic-release/lib/git')

Expand All @@ -13,42 +11,44 @@ module.exports = publish
* 3. Perform the release using the mvn command
* 4. Make another commit updating to the next snapshot version
*/
async function publish (pluginConfig, publishConfig) {
const {options, nextRelease} = publishConfig
async function publish (pluginConfig, context) {
const {logger, nextRelease, options} = context

// configure git to allow pushing
await configureGit(options.repositoryUrl)
await configureGit(options.repositoryUrl, logger)

// set and commit version number in pom.xml
await commitVersionInPomXml(nextRelease.version)
await commitVersionInPomXml(nextRelease.version, logger)

debug('Deploying version %s with maven', nextRelease.version)
logger.log('Deploying version %s with maven', nextRelease.version)
try {
await exec('mvn', ['deploy', '--settings', 'maven-settings.xml'])
} catch (e) {
logger.error('failed to deploy to maven')
logger.error(e)
throw new Error('failed to deploy to maven')
}

// tag and create a release on github
nextRelease.gitHead = await getGitHead()
await semanticGithub.publish(pluginConfig, publishConfig)
await semanticGithub.publish(pluginConfig, context)

// update version to next snapshot version
const nextSnapshotVersion = nextRelease.version.split('.').map(s => parseInt(s, 10))
nextSnapshotVersion[2] += 1

// make a commit bumping to snapshot version
await commitVersionInPomXml(`${nextSnapshotVersion.join('.')}-SNAPSHOT`)
await commitVersionInPomXml(`${nextSnapshotVersion.join('.')}-SNAPSHOT`, logger)
}

/**
* Configure git settings. Copied from this guide: https://gist.github.com/willprice/e07efd73fb7f13f917ea
*/
async function configureGit (repositoryUrl) {
debug('configuring git')
async function configureGit (repositoryUrl, logger) {
logger.log('configuring git')

// run bash script to make sure we're on the master branch and not in detached head mode
debug('resolving and checking out current branch')
logger.log('resolving and checking out current branch')

// verify integrity of build
const headRef = await execa.stdout('git', ['rev-parse', 'HEAD'])
Expand Down Expand Up @@ -88,40 +88,24 @@ function exec () {
/**
* Change the pom.xml file, commit the change and then push it to the repo
*/
async function commitVersionInPomXml (versionStr) {
let pomLines
try {
pomLines = (await fs.readFile('./pom.xml', 'utf8')).split('\n')
} catch (e) {
debug(e)
throw new Error('Error reading pom.xml')
}

// manually iterate through lines and make edits to
// preserve formatting and comments of file
for (let i = 0; i < pomLines.length; i++) {
const line = pomLines[i]
if (line.indexOf('<!-- semantic-release-version-line -->') > -1) {
// edit version field
pomLines[i] = line.replace(/<version>(.*)<\/version>/, `<version>${versionStr}</version>`)
break
}
}

await fs.writeFile('./pom.xml', pomLines.join('\n'))
async function commitVersionInPomXml (versionStr, logger) {
await exec(
'mvn',
['versions:set', 'versions:commit', `-DnewVersion=${versionStr}`]
)

const commitMessage = versionStr.indexOf('SNAPSHOT') > -1
? `Prepare next development iteration ${versionStr} [ci skip]`
: `${versionStr} [ci skip]`

debug('adding pom.xml to a commmit')
await exec('git', ['add', 'pom.xml'])
logger.log('adding pom.xml to a commmit')
await exec('git', ['add', '**/pom.xml'])

debug('committing changes')
logger.log('committing changes')
await exec('git', ['commit', '-m', commitMessage])
process.stdout.write('\n')

debug('pushing changes')
logger.log('pushing changes')
const token = process.env.GH_TOKEN || process.env.GITHUB_TOKEN
// don't pipe to stdout in case token is shown
await execa(
Expand Down
132 changes: 132 additions & 0 deletions lib/verify-release.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
const fs = require('fs-extra')
const got = require('got')
const semver = require('semver')
const xml2js = require('xml2js-es6-promise')

/**
* Get the last release of the maven repository
*/
module.exports = async function verify (pluginConfig, context) {
const {logger} = context
logger.log('begin maven verify')

process.chdir('../maven-semantic-release-example') // for testing

let pomXml
try {
pomXml = await getPomInfo()
} catch (e) {
logger.error(e)
throw e
}

const pomVersion = pomXml.project.version[0]
const mavenCentralVersion = await getLatestVersionFromMavenCentral(
pomXml,
logger
)
const lastReleaseVersion = context.lastRelease.version

if (!semver.valid(mavenCentralVersion)) {
logger.log(
'WARNING: maven central version of %s is an invalid semver version',
mavenCentralVersion
)
}

if (!semver.valid(pomVersion)) {
logger.log(
'WARNING: pom.xml version of %s is an invalid semver version',
pomVersion
)
}

if (
semver.inc(mavenCentralVersion, 'patch') !==
semver.inc(pomVersion, 'patch')
) {
logger.log(
'WARNING: maven central version of %s differs widely from pom version of %s',
mavenCentralVersion,
pomVersion
)
}

if (lastReleaseVersion !== mavenCentralVersion) {
logger.log(
'WARNING: maven central version of %s differs from last version of %s found in git history',
mavenCentralVersion,
lastReleaseVersion
)
}

if (semver.inc(lastReleaseVersion, 'patch') !== semver.inc(pomVersion, 'patch')) {
throw new Error(
`pom.xml version of ${pomVersion} differs too much from last git tag version of ${lastReleaseVersion}`
)
}
}

// get package info from pom.xml
async function getPomInfo () {
const pomXmlFilePath = './pom.xml'
const stats = await fs.stat('./pom.xml')

if (!stats) {
throw new Error('pom.xml file is missing!')
}

let pomXml
try {
const pomContents = await fs.readFile(pomXmlFilePath, 'utf8')
pomXml = await xml2js(pomContents)
} catch (e) {
throw new Error('Error reading pom.xml')
}

if (
!pomXml ||
!pomXml.project ||
!pomXml.project.groupId ||
pomXml.project.groupId.length === 0 ||
!pomXml.project.artifactId ||
pomXml.project.artifactId.length === 0
) {
throw new Error('pom.xml is missing groupId or artifactId')
}

if (!pomXml.project.version) {
throw new Error('Version is missing from pom.xml')
}

return pomXml
}

/**
* Search for the maven project on maven central and return the release number
* of the latest version. Return nothing if none found.
*/
async function getLatestVersionFromMavenCentral (pomXml, logger) {
const searchTerm = `${pomXml.project.groupId[0]}.${pomXml.project.artifactId[0]}`

// get the last semver version from published repo
logger.log('searching maven for term %s', searchTerm)
const mavenCentralJson = await got(
`https://search.maven.org/solrsearch/select?q=${searchTerm}&rows=20&wt=json`,
{ json: true }
)

if (
!mavenCentralJson ||
!mavenCentralJson.body ||
!mavenCentralJson.body.response ||
!mavenCentralJson.body.response.docs ||
mavenCentralJson.body.response.docs.length === 0
) {
logger.log('No version found of package %s found on %s', searchTerm, 'maven central')
return
}

// (dangerously) assume first doc is the one we're looking for
return mavenCentralJson.body.response.docs[0].latestVersion
}
8 changes: 3 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,15 @@
"license": "MIT",
"private": false,
"dependencies": {
"debug": "^3.1.0",
"env-ci": "^1.2.0",
"execa": "^0.9.0",
"fs-extra": "^5.0.0",
"got": "^8.0.1",
"semantic-release": "11.2.0",
"semantic-release": "^15.8.1",
"semver": "^5.5.0",
"xml2js-es6-promise": "^1.1.1"
},
"devDependencies": {
"mastarm": "^4.1.0",
"travis-deploy-once": "^4.3.4"
"mastarm": "^4.1.0"
},
"scripts": {
"test": "mastarm lint bin lib",
Expand Down
Loading

0 comments on commit 70b3dc6

Please sign in to comment.