From 3e37a48d08c582cf538685b50034822718d818cd Mon Sep 17 00:00:00 2001 From: Eric Hayes Date: Tue, 19 Jul 2022 11:34:35 -0700 Subject: [PATCH 1/2] Add support for alias tags for canary (if pull request), pre-releases (with mapping to specific aliases per branch), and latest. All docker alias tags are also pushed to git --- plugins/docker/README.md | 56 ++++- plugins/docker/__tests__/docker.test.ts | 308 +++++++++++++++++++++++- plugins/docker/src/index.ts | 119 +++++++-- 3 files changed, 452 insertions(+), 31 deletions(-) diff --git a/plugins/docker/README.md b/plugins/docker/README.md index 148cbb272..3d5c04e3e 100644 --- a/plugins/docker/README.md +++ b/plugins/docker/README.md @@ -18,33 +18,73 @@ yarn add -D @auto-it/docker ## Usage -You must first must build the desired image to publish. +**IMPORTANT:** You must first must build the desired image to publish. -These environment variables tell `auto` what to publish. +The following options are available for this plugin: -- IMAGE - The image ID, digest, or tag of the locally available image to tag and publish. This is required unless you want to statically tag the local image, in which case you can provide it as an option. +|option|required|default|environment variable|description| +|-|-|-|-|-| +| `image` | X | | `IMAGE` | The image ID, digest, or tag of the locally available image to tag and publish (must be built before this plugin is run) | +| `registry` | X | | `REGISTRY` | Docker registry to publish to | +| `tagLatest` | | `false` | `TAG_LATEST` | Tag latest release with `latest` tag | +| `tagPullRequestAliases` | | `false` | `TAG_PULL_REQUEST_ALIASES` | Tag pull requests with `pr-` tag | +| `tagPrereleaseAliases` | | `false` | `TAG_PRERELEASE_ALIASES` | Tag prerelease branches +| `prereleaseAliasMappings` | | `{}` | | Tag prerelease branches with different names (e.g. `{"develop": "next"}`) | +### Example 1: Tag releases only ```json { "plugins": [ - ["docker", { "registry": "ghcr.io/my/app" }] + ["docker", { "registry": "ghcr.io/my/app", "image": "someLocalImage:myLocalTag" }] // other plugins ] } ``` -If you'd like to tag releases with `latest` too, you can specify the `tagLatest` option: +This will publish releases from the local docker image `someLocalImage:myLocalTag` to: - `ghcr.io/my/app:` +### Example 2: Tag latest releases ```json { - "plugins": [["docker", { "registry": "ghcr.io/my/app", "tagLatest": true }]] + "plugins": [ + ["docker", { "registry": "ghcr.io/my/app", "image": "someLocalImage:myLocalTag", "tagLatest": true }] + // other plugins + ] } ``` -If you're tagging the locally built image in a static manner, you can also pass `image` instead of `IMAGE` as an environment variable. +This will publish releases from the local docker image `someLocalImage:myLocalTag` to: - `ghcr.io/my/app:` +- `ghcr.io/my/app:latest` +### Example 3: Tag Prereleases (with Custom Tags) ```json { - "plugins": [["docker", { "registry": "ghcr.io/my/app", "image": "myapp" }]] + "prereleaseBranches": ["develop", "someOtherPrereleaseBranch"], + "plugins": [ + ["docker", { "registry": "ghcr.io/my/app", "image": "someLocalImage:myLocalTag", "tagPrereleases": true, "prereleaseTagMapping": { "develop": "next" } }] + // other plugins + ] } ``` + +For pushes to `develop` branch this will create the following tags: +- `ghcr.io/my/app:` +- `ghcr.io/my/app:next` + +For pushes to `someOtherReleaseBranch` this will create the following tags: +- `ghcr.io/my/app:` +- `ghcr.io/my/app:someOtherReleaseBranch` + +### Example 4: Tag Pull Requests +```json +{ + "plugins": [ + ["docker", { "registry": "ghcr.io/my/app", "image": "someLocalImage:myLocalTag", "tagPullRequests": true }] + // other plugins + ] +} +``` + +If this is run against a pull request the following tags will be created against `someLocalImage:myLocalTag`: +- `ghcr.io/my/app:` +- `ghcr.io/my/app:pr-` diff --git a/plugins/docker/__tests__/docker.test.ts b/plugins/docker/__tests__/docker.test.ts index 9fd38fa49..4f9c21959 100644 --- a/plugins/docker/__tests__/docker.test.ts +++ b/plugins/docker/__tests__/docker.test.ts @@ -18,7 +18,8 @@ const registry = "registry.io/app"; const setup = ( mockGit?: any, options?: IDockerPluginOptions, - checkEnv?: jest.SpyInstance + checkEnv?: jest.SpyInstance, + prereleaseBranches: string[] = ["next"], ) => { const plugin = new DockerPlugin(options || { registry }); const hooks = makeHooks(); @@ -30,7 +31,7 @@ const setup = ( remote: "origin", logger: dummyLog(), prefixRelease: (r: string) => r, - config: { prereleaseBranches: ["next"] }, + config: { prereleaseBranches }, getCurrentVersion: () => "v1.0.0", } as unknown) as Auto.Auto); @@ -65,7 +66,7 @@ describe("Docker Plugin", () => { await hooks.beforeRun.promise({ plugins: [["docker", { registry }]], } as any); - expect(checkEnv).toBeCalled(); + expect(checkEnv).toBeCalledWith('docker', 'IMAGE'); }); test("shouldn't check env with image", async () => { @@ -74,7 +75,79 @@ describe("Docker Plugin", () => { await hooks.beforeRun.promise({ plugins: [["docker", { registry, image: "test" }]], } as any); - expect(checkEnv).not.toBeCalled(); + expect(checkEnv).not.toBeCalledWith('docker','IMAGE'); + }); + + test("should check env without registry", async () => { + const checkEnv = jest.fn(); + const hooks = setup(undefined, undefined, checkEnv); + await hooks.beforeRun.promise({ + plugins: [["docker", { }]], + } as any); + expect(checkEnv).toHaveBeenCalledWith('docker','REGISTRY'); + }); + + test("shouldn't check env with registry", async () => { + const checkEnv = jest.fn(); + const hooks = setup(undefined, undefined, checkEnv); + await hooks.beforeRun.promise({ + plugins: [["docker", { registry, image: "test" }]], + } as any); + expect(checkEnv).not.toHaveBeenCalledWith('docker','REGISTRY'); + }); + + test("should check env without tagLatest", async () => { + const checkEnv = jest.fn(); + const hooks = setup(undefined, undefined, checkEnv); + await hooks.beforeRun.promise({ + plugins: [["docker", { }]], + } as any); + expect(checkEnv).toHaveBeenCalledWith('docker','TAG_LATEST'); + }); + + test("shouldn't check env with tagLatest", async () => { + const checkEnv = jest.fn(); + const hooks = setup(undefined, undefined, checkEnv); + await hooks.beforeRun.promise({ + plugins: [["docker", { tagLatest: true }]], + } as any); + expect(checkEnv).not.toHaveBeenCalledWith('docker','TAG_LATEST'); + }); + + test("should check env without tagPrereleases", async () => { + const checkEnv = jest.fn(); + const hooks = setup(undefined, undefined, checkEnv); + await hooks.beforeRun.promise({ + plugins: [["docker", { }]], + } as any); + expect(checkEnv).toHaveBeenCalledWith('docker','TAG_PRERELEASE_ALIASES'); + }); + + test("shouldn't check env with tagPrereleases", async () => { + const checkEnv = jest.fn(); + const hooks = setup(undefined, undefined, checkEnv); + await hooks.beforeRun.promise({ + plugins: [["docker", { tagPrereleaseAliases: true }]], + } as any); + expect(checkEnv).not.toHaveBeenCalledWith('docker','TAG_PRERELEASE_ALIASES'); + }); + + test("should check env without tagPullRequests", async () => { + const checkEnv = jest.fn(); + const hooks = setup(undefined, undefined, checkEnv); + await hooks.beforeRun.promise({ + plugins: [["docker", { }]], + } as any); + expect(checkEnv).toHaveBeenCalledWith('docker','TAG_PULL_REQUEST_ALIASES'); + }); + + test("shouldn't check env with tagPullRequests", async () => { + const checkEnv = jest.fn(); + const hooks = setup(undefined, undefined, checkEnv); + await hooks.beforeRun.promise({ + plugins: [["docker", { tagPullRequestAliases: true }]], + } as any); + expect(checkEnv).not.toHaveBeenCalledWith('docker','TAG_PULL_REQUEST_ALIASES'); }); }); @@ -149,6 +222,12 @@ describe("Docker Plugin", () => { "-m", '"Update version to 1.0.1"', ]); + expect(exec).toHaveBeenCalledWith("git", [ + "tag", + "latest", + "-mf", + '"Tag release alias: latest (1.0.1)"', + ]); expect(exec).toHaveBeenCalledWith("docker", [ "tag", sourceImage, @@ -192,6 +271,91 @@ describe("Docker Plugin", () => { "push", `${registry}:1.0.1-canary.123.1`, ]); + expect(exec).toBeCalledTimes(2); + }); + + test("should not tag canary version aliases if not a pull request", async () => { + const sourceImage = "app:sha-123"; + const hooks = setup( + { + getLatestRelease: () => "v1.0.0", + getCurrentVersion: () => "v1.0.0", + }, + { registry, image: sourceImage, tagPullRequestAliases: true } + ); + + const prSpy = jest.spyOn(Auto,"getPrNumberFromEnv").mockImplementation(jest.fn()); + + await hooks.canary.promise({ + bump: Auto.SEMVER.patch, + canaryIdentifier: `canary.123.1`, + }); + + expect(prSpy).toBeCalled(); + + expect(exec).toHaveBeenCalledWith("docker", [ + "tag", + sourceImage, + `${registry}:1.0.1-canary.123.1`, + ]); + expect(exec).toHaveBeenCalledWith("docker", [ + "push", + `${registry}:1.0.1-canary.123.1`, + ]); + expect(exec).toBeCalledTimes(2); + }); + + test("should tag canary version aliases", async () => { + const prNumber = 123; + const sourceImage = "app:sha-123"; + const hooks = setup( + { + getLatestRelease: () => "v1.0.0", + getCurrentVersion: () => "v1.0.0", + }, + { registry, image: sourceImage, tagPullRequestAliases: true } + ); + + const prSpy = jest.spyOn(Auto,"getPrNumberFromEnv").mockImplementationOnce(() => prNumber); + + await hooks.canary.promise({ + bump: Auto.SEMVER.patch, + canaryIdentifier: `canary.${prNumber}.1`, + }); + + expect(prSpy).toBeCalled(); + + expect(exec).toHaveBeenCalledWith("docker", [ + "tag", + sourceImage, + `${registry}:1.0.1-canary.${prNumber}.1`, + ]); + expect(exec).toHaveBeenCalledWith("docker", [ + "push", + `${registry}:1.0.1-canary.${prNumber}.1`, + ]); + expect(exec).toHaveBeenCalledWith("git", [ + "tag", + `pr-${prNumber}`, + "-mf", + `Tag pull request canary: pr-${prNumber} (1.0.1-canary.${prNumber}.1)`, + ]); + expect(exec).toHaveBeenCalledWith("git", [ + "push", + "origin", + `refs/tags/pr-${prNumber}`, + "-f" + ]) + expect(exec).toHaveBeenCalledWith("docker", [ + "tag", + sourceImage, + `${registry}:pr-${prNumber}`, + ]); + expect(exec).toHaveBeenCalledWith("docker", [ + "push", + `${registry}:pr-${prNumber}`, + ]); + expect(exec).toBeCalledTimes(6); }); test("should print canary version in dry run", async () => { @@ -227,6 +391,133 @@ describe("Docker Plugin", () => { expect(exec).not.toHaveBeenCalled(); }); + test("should tag next version with alias", async () => { + const sourceImage = "app:sha-123" + const hooks = setup( + { + getLatestRelease: () => "v0.1.0", + getLastTagNotInBaseBranch: () => "v1.0.0", + }, + { + registry, + image: sourceImage, + tagPrereleaseAliases: true + }, + ) + + await hooks.next.promise([], { bump: Auto.SEMVER.patch } as any); + + expect(exec).toHaveBeenCalledWith("git", [ + "tag", + "1.0.1-next.0", + "-m", + '"Tag pre-release: 1.0.1-next.0"', + ]); + expect(exec).toHaveBeenCalledWith("git", [ + "tag", + "next", + "-mf", + '"Tag pre-release alias: next (1.0.1-next.0)"', + ]); + expect(exec).toHaveBeenCalledWith("git", [ + "push", + "origin", + "refs/tags/next", + "-f" + ]) + expect(exec).toHaveBeenCalledWith("git", [ + "push", + "origin", + "next", + "--tags", + ]); + expect(exec).toHaveBeenCalledWith("docker", [ + "tag", + sourceImage, + `${registry}:1.0.1-next.0`, + ]); + expect(exec).toHaveBeenCalledWith("docker", [ + "tag", + sourceImage, + `${registry}:next`, + ]); + expect(exec).toHaveBeenCalledWith("docker", [ + "push", + `${registry}:1.0.1-next.0`, + ]); + expect(exec).toHaveBeenCalledWith("docker", [ + "push", + `${registry}:next`, + ]); + expect(exec).toHaveBeenCalledTimes(8); + }); + + test("should tag next version with alias mappings", async () => { + const sourceImage = "app:sha-123"; + const expectedAlias = "someOtherAlias"; + + const hooks = setup( + { + getLatestRelease: () => "v0.1.0", + getLastTagNotInBaseBranch: () => "v1.0.0", + }, + { + registry, + image: sourceImage, + tagPrereleaseAliases: true, + prereleaseAliasMappings: { + "next": expectedAlias + } + }, + ) + + await hooks.next.promise([], { bump: Auto.SEMVER.patch } as any); + + expect(exec).toHaveBeenCalledWith("git", [ + "tag", + `1.0.1-${expectedAlias}.0`, + "-m", + `"Tag pre-release: 1.0.1-${expectedAlias}.0"`, + ]); + expect(exec).toHaveBeenCalledWith("git", [ + "tag", + expectedAlias, + "-mf", + `"Tag pre-release alias: ${expectedAlias} (1.0.1-${expectedAlias}.0)"`, + ]); + expect(exec).toHaveBeenCalledWith("git", [ + "push", + "origin", + `refs/tags/${expectedAlias}`, + "-f" + ]) + expect(exec).toHaveBeenCalledWith("git", [ + "push", + "origin", + "next", + "--tags", + ]); + expect(exec).toHaveBeenCalledWith("docker", [ + "tag", + sourceImage, + `${registry}:1.0.1-${expectedAlias}.0`, + ]); + expect(exec).toHaveBeenCalledWith("docker", [ + "tag", + sourceImage, + `${registry}:${expectedAlias}`, + ]); + expect(exec).toHaveBeenCalledWith("docker", [ + "push", + `${registry}:1.0.1-${expectedAlias}.0`, + ]); + expect(exec).toHaveBeenCalledWith("docker", [ + "push", + `${registry}:${expectedAlias}`, + ]); + expect(exec).toHaveBeenCalledTimes(8); + }); + test("should tag next version", async () => { const sourceImage = "app:sha-123"; const hooks = setup( @@ -260,6 +551,7 @@ describe("Docker Plugin", () => { "push", `${registry}:1.0.1-next.0`, ]); + expect(exec).toHaveBeenCalledTimes(4); }); test("return next version in dry run", async () => { @@ -316,6 +608,14 @@ describe("Docker Plugin", () => { await hooks.version.promise({ bump: Auto.SEMVER.patch }); await hooks.publish.promise({ bump: Auto.SEMVER.patch }); + + expect(exec).toHaveBeenCalledWith("git", [ + "push", + "origin", + "refs/tags/latest", + "-f" + ]); + expect(exec).toHaveBeenCalledWith("docker", [ "push", `${registry}:1.0.1`, diff --git a/plugins/docker/src/index.ts b/plugins/docker/src/index.ts index 8237a2659..e2ff93033 100644 --- a/plugins/docker/src/index.ts +++ b/plugins/docker/src/index.ts @@ -6,22 +6,38 @@ import { getCurrentBranch, DEFAULT_PRERELEASE_BRANCHES, validatePluginConfiguration, + getPrNumberFromEnv, } from "@auto-it/core"; import * as t from "io-ts"; import { inc, ReleaseType } from "semver"; -const pluginOptions = t.intersection([ - t.interface({ - /** The target registry to push too */ - registry: t.string, - }), - t.partial({ - /** Whether to tag non-prerelease images with latest */ - tagLatest: t.boolean, - /** The source image, if a static name and/or tag */ - image: t.string, - }), -]); +const pluginOptions = t.partial({ + /** The source image, if a static name and/or tag */ + image: t.string, + /** The target registry to push too */ + registry: t.string, + /** Whether to tag non-prerelease images with latest alias tag */ + tagLatest: t.boolean, + /** Whether to tag prereleases with alias tags too */ + tagPrereleaseAliases: t.boolean, + /** Whether to tag pull requests with alias tags */ + tagPullRequestAliases: t.boolean, + /** Prerelease alias tag mappings (BRANCH=ALIAS_NAME) */ + prereleaseAliasMappings: t.record(t.string, t.string), +}); + +/** Convert string/number to boolean value */ +function toBoolean(v?: string|number) { + return String(v).search(/(true|1)/i) >= 0 +} + +enum DOCKER_PLUGIN_ENV_VARS { + IMAGE = 'IMAGE', + REGISTRY = 'REGISTRY', + TAG_LATEST = 'TAG_LATEST', + TAG_PRERELEASE_ALIASES = 'TAG_PRERELEASE_ALIASES', + TAG_PULL_REQUEST_ALIASES = 'TAG_PULL_REQUEST_ALIASES' +} export type IDockerPluginOptions = t.TypeOf; @@ -35,7 +51,12 @@ export default class DockerPlugin implements IPlugin { /** Initialize the plugin with it's options */ constructor(private readonly options: IDockerPluginOptions) { - this.options.image = options.image || process.env.IMAGE; + this.options.image = options.image || process.env[DOCKER_PLUGIN_ENV_VARS.IMAGE]; + this.options.registry = options.registry || process.env[DOCKER_PLUGIN_ENV_VARS.REGISTRY]; + this.options.tagLatest = options.tagLatest || toBoolean(process.env[DOCKER_PLUGIN_ENV_VARS.TAG_LATEST]); + this.options.tagPrereleaseAliases = options.tagPrereleaseAliases || toBoolean(process.env[DOCKER_PLUGIN_ENV_VARS.TAG_PRERELEASE_ALIASES]); + this.options.tagPullRequestAliases = options.tagPullRequestAliases || toBoolean(process.env[DOCKER_PLUGIN_ENV_VARS.TAG_PULL_REQUEST_ALIASES]); + this.options.prereleaseAliasMappings = options.prereleaseAliasMappings || {}; } /** Tap into auto plugin points. */ @@ -61,7 +82,23 @@ export default class DockerPlugin implements IPlugin { plugin[0] === this.name || plugin[0] === `@auto-it/${this.name}` ) as [string, IDockerPluginOptions]; if (!dockerPlugin?.[1]?.image) { - auto.checkEnv(this.name, "IMAGE"); + auto.checkEnv(this.name, DOCKER_PLUGIN_ENV_VARS.IMAGE); + } + + if (!dockerPlugin?.[1]?.registry) { + auto.checkEnv(this.name, DOCKER_PLUGIN_ENV_VARS.REGISTRY); + } + + if (!dockerPlugin?.[1]?.tagLatest) { + auto.checkEnv(this.name, DOCKER_PLUGIN_ENV_VARS.TAG_LATEST); + } + + if (!dockerPlugin?.[1]?.tagPrereleaseAliases) { + auto.checkEnv(this.name, DOCKER_PLUGIN_ENV_VARS.TAG_PRERELEASE_ALIASES); + } + + if (!dockerPlugin?.[1]?.tagPullRequestAliases) { + auto.checkEnv(this.name, DOCKER_PLUGIN_ENV_VARS.TAG_PULL_REQUEST_ALIASES); } }); @@ -84,12 +121,13 @@ export default class DockerPlugin implements IPlugin { const lastTag = await getTag(); const newTag = inc(lastTag, bump as ReleaseType); + const aliasTag = "latest"; if (dryRun && newTag) { if (quiet) { - console.log(newTag); + console.log(this.options.tagLatest ? [newTag, aliasTag].join(', ') : newTag); } else { - auto.logger.log.info(`Would have published: ${newTag}`); + auto.logger.log.info(`Would have published: ${this.options.tagLatest ? [newTag, aliasTag].join(', ') : newTag}`); } return; @@ -110,6 +148,15 @@ export default class DockerPlugin implements IPlugin { `"Update version to ${prefixedTag}"`, ]); + if (this.options.tagLatest) { + await execPromise("git", [ + "tag", + aliasTag, + "-mf", + `"Tag release alias: ${aliasTag} (${prefixedTag})"` + ]); + } + await execPromise("docker", [ "tag", this.options.image, @@ -140,11 +187,14 @@ export default class DockerPlugin implements IPlugin { const nextVersion = inc(current, bump as ReleaseType); const canaryVersion = `${nextVersion}-${canaryIdentifier}`; + const prNumber = getPrNumberFromEnv(); + const canaryAliasVersion = `pr-${prNumber}`; + if (dryRun) { if (quiet) { - console.log(canaryVersion); + console.log(prNumber ? [canaryVersion, canaryAliasVersion].join(', ') : canaryVersion); } else { - auto.logger.log.info(`Would have published: ${canaryVersion}`); + auto.logger.log.info(`Would have published: ${prNumber ? [canaryVersion, canaryAliasVersion].join(', ') : canaryVersion}`); } return; @@ -155,6 +205,14 @@ export default class DockerPlugin implements IPlugin { await execPromise("docker", ["tag", this.options.image, targetImage]); await execPromise("docker", ["push", targetImage]); + if (prNumber && this.options.tagPullRequestAliases) { + const aliasImage = `${this.options.registry}:${canaryAliasVersion}`; + await execPromise("docker", ["tag", this.options.image, aliasImage]); + await execPromise("docker", ["push", aliasImage]); + await execPromise("git", ["tag", `${canaryAliasVersion}`, "-mf", `Tag pull request canary: ${canaryAliasVersion} (${canaryVersion})`]); + await execPromise("git", ["push", auto.remote, `refs/tags/${canaryAliasVersion}`, "-f"]); + } + auto.logger.verbose.info("Successfully published canary version"); return canaryVersion; } @@ -173,6 +231,8 @@ export default class DockerPlugin implements IPlugin { const prereleaseBranch = prereleaseBranches.includes(branch) ? branch : prereleaseBranches[0]; + const prereleaseAlias = (this.options.prereleaseAliasMappings as {[key: string]: string})[prereleaseBranch] ?? prereleaseBranch; + const lastRelease = await auto.git.getLatestRelease(); const current = (await auto.git.getLastTagNotInBaseBranch(prereleaseBranch)) || @@ -181,12 +241,17 @@ export default class DockerPlugin implements IPlugin { lastRelease, current, bump, - prereleaseBranch + prereleaseAlias ); const targetImage = `${this.options.registry}:${prerelease}`; + const aliasImage = `${this.options.registry}:${prereleaseAlias}`; preReleaseVersions.push(prerelease); + if (this.options.tagPrereleaseAliases) { + preReleaseVersions.push(aliasImage); + } + if (dryRun) { return preReleaseVersions; } @@ -201,6 +266,18 @@ export default class DockerPlugin implements IPlugin { await execPromise("docker", ["push", targetImage]); await execPromise("git", ["push", auto.remote, branch, "--tags"]); + if (this.options.tagPrereleaseAliases) { + await execPromise("git", [ + "tag", + prereleaseAlias, + "-mf", + `"Tag pre-release alias: ${prereleaseAlias} (${prerelease})"`, + ]); + await execPromise("docker", ["tag", this.options.image, aliasImage]); + await execPromise("docker", ["push", aliasImage]); + await execPromise("git", ["push", auto.remote, `refs/tags/${prereleaseAlias}`, "-f"]); + } + return preReleaseVersions; } ); @@ -214,6 +291,10 @@ export default class DockerPlugin implements IPlugin { ) ); + if (this.options.tagLatest) { + await execPromise("git", ["push", auto.remote, `refs/tags/latest`, "-f"]); + } + await execPromise("git", [ "push", "--follow-tags", From 81d7bb2888c61c8bac5a07be313ade914e869d6f Mon Sep 17 00:00:00 2001 From: Eric Hayes Date: Tue, 19 Jul 2022 22:46:50 -0700 Subject: [PATCH 2/2] Update README.md --- plugins/docker/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/docker/README.md b/plugins/docker/README.md index 3d5c04e3e..a9885926b 100644 --- a/plugins/docker/README.md +++ b/plugins/docker/README.md @@ -61,7 +61,7 @@ This will publish releases from the local docker image `someLocalImage:myLocalTa { "prereleaseBranches": ["develop", "someOtherPrereleaseBranch"], "plugins": [ - ["docker", { "registry": "ghcr.io/my/app", "image": "someLocalImage:myLocalTag", "tagPrereleases": true, "prereleaseTagMapping": { "develop": "next" } }] + ["docker", { "registry": "ghcr.io/my/app", "image": "someLocalImage:myLocalTag", "tagPrereleaseAliases": true, "prereleaseAliasMapping": { "develop": "next" } }] // other plugins ] } @@ -79,7 +79,7 @@ For pushes to `someOtherReleaseBranch` this will create the following tags: ```json { "plugins": [ - ["docker", { "registry": "ghcr.io/my/app", "image": "someLocalImage:myLocalTag", "tagPullRequests": true }] + ["docker", { "registry": "ghcr.io/my/app", "image": "someLocalImage:myLocalTag", "tagPullRequestAliases": true }] // other plugins ] }