Skip to content

Commit

Permalink
feat: skipTags registry option
Browse files Browse the repository at this point in the history
  • Loading branch information
Róbert Kiss authored and lgaticaq committed Oct 18, 2021
1 parent e1aa3db commit bf52afc
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 5 deletions.
11 changes: 11 additions & 0 deletions src/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,17 @@ module.exports = new Map([
message: 'Error tag docker push.',
details: 'Error tag docker push. Check credentials in `registries`.'
})
],
[
'ESKIPTAGSNOTANARRAY',
/**
* @param {Context} ctx -
* @returns {SemanticReleaseError} -
*/
ctx => ({
message: 'Invalid registry config.',
details: 'Invalid registry config. 1 or more `registry` config contains the `skipTags` property but it is not an array. Please check it.'
})
]
])
/* eslint-enable sonarjs/no-duplicate-string */
19 changes: 19 additions & 0 deletions src/is-tag-push-allowed.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* @typedef {import('./types').Registry} Registry
*/
/**
* @param {string } tag -
* @param {Registry} registry -
* @returns {boolean} -
* @example
* isTagPushAllowed(tag, registry)
*/
const isTagPushAllowed = (tag, registry) => {
if (!registry.skipTags) {
return true
}

return !registry.skipTags.includes(tag)
}

module.exports = isTagPushAllowed
13 changes: 9 additions & 4 deletions src/publish.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const Dockerode = require('dockerode')

const getError = require('./get-error')
const getAuth = require('./getAuth')
const isTagPushAllowed = require('./is-tag-push-allowed')

/** @typedef {import('stream').Readable} ReadableStream */
/**
Expand Down Expand Up @@ -67,10 +68,14 @@ module.exports = async (pluginConfig, ctx) => {
username: user
}
for (const tag of tags) {
ctx.logger.log(`Pushing docker image ${imageName}:${tag}`)
const response = await image.push({ tag, ...options })
// @ts-ignore
await pushImage(response)
if (isTagPushAllowed(tag, registry)) {
ctx.logger.log(`Pushing docker image ${imageName}:${tag}`)
const response = await image.push({ tag, ...options })
// @ts-ignore
await pushImage(response)
} else {
ctx.logger.log(`Skip push docker image ${imageName}:${tag}`)
}
}
}
} catch (err) {
Expand Down
1 change: 1 addition & 0 deletions src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface Registry {
imageName?: string
user?: string
password?: string
skipTags?: string[];
}

export interface Config extends SemanticReleaseConfig {
Expand Down
6 changes: 5 additions & 1 deletion src/verify.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ module.exports = async (pluginConfig, ctx) => {
if (!pluginConfig.registries || pluginConfig.registries.length === 0) {
errors.push(getError('ENOREGISTRY', ctx))
} else {
for (const { user, password, url, imageName } of pluginConfig.registries) {
for (const { user, password, url, imageName, skipTags } of pluginConfig.registries) {
if (skipTags && !Array.isArray(skipTags)) {
errors.push(getError('ESKIPTAGSNOTANARRAY', ctx))
}

try {
getAuth(user, password, url, imageName, ctx)
// eslint-disable-next-line security/detect-object-injection
Expand Down
24 changes: 24 additions & 0 deletions test/publish.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,13 @@ describe('Publish', () => {
}
]
}
let dockerPushArgs

before(() => {
class DockerImage {
push ({ tag, password, serveraddress, username }) {
dockerPushArgs.push({ tag, password, serveraddress, username })

return new Promise((resolve, reject) => {
const response = new MyEmitter()
setTimeout(() => {
Expand All @@ -53,6 +56,11 @@ describe('Publish', () => {
publish = require('../src/publish')
})

// eslint-disable-next-line no-undef
beforeEach(() => {
dockerPushArgs = []
})

it('expect a EDOCKERIMAGEPUSH error', async () => {
try {
await publish(pluginConfig, ctx)
Expand All @@ -67,10 +75,26 @@ describe('Publish', () => {
pluginConfig.registries[0].url = 'registry.example.com'
pluginConfig.additionalTags = ['beta']
expect(await publish(pluginConfig, ctx)).to.be.a('undefined')
// eslint-disable-next-line no-unused-expressions
expect(isTagPublished('latest')).to.be.true
// eslint-disable-next-line no-unused-expressions
expect(isTagPublished('beta')).to.be.true
})

it('expect skip "latest" publish', async () => {
pluginConfig.registries[0].url = 'registry.example.com'
pluginConfig.registries[0].skipTags = ['latest']
expect(await publish(pluginConfig, ctx)).to.be.a('undefined')
// eslint-disable-next-line no-unused-expressions
expect(isTagPublished('latest')).to.be.false
})

after(() => {
mock.stopAll()
})

const isTagPublished = (tag) => {
return dockerPushArgs.some(arg => arg.tag === tag)
}
})
/* eslint-enable require-jsdoc */
13 changes: 13 additions & 0 deletions test/verify.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,19 @@ describe('Verify', () => {
}
})

it('expect a ESKIPTAGSNOTANARRAY error', async () => {
try {
pluginConfig.registries[0].skipTags = 'latest'
await verify(pluginConfig, { env })
} catch (errs) {
const err = errs._errors[0]
expect(err.name).to.equal('SemanticReleaseError')
expect(err.code).to.equal('ESKIPTAGSNOTANARRAY')
} finally {
pluginConfig.registries[0].skipTags = undefined
}
})

it('expect success verify', async () => {
env.DOCKER_USER = 'user'
expect(await verify(pluginConfig, { env })).to.be.a('undefined')
Expand Down

0 comments on commit bf52afc

Please sign in to comment.