Compare commits

...

13 Commits

Author SHA1 Message Date
Shubham Agrawal b1c01c18ff Fix drone yml 2022-03-31 15:25:32 +05:30
Shubham Agrawal a11da49965 Publish plugin with latest kaniko 1.8.0 image (#43) 2022-03-31 14:53:50 +05:30
HC Saustrup fae9271dc7 fix: Build.Repo and Build.CacheRepo now uses buildRepo() (#40) 2022-03-15 12:13:05 +05:30
JimZhang 8bd45524d4 add flag --registry-mirrors (#42) 2022-03-15 11:45:57 +05:30
Aman Singh 427f9abb99 Upgraded golang version (#41) 2022-03-14 22:19:32 +05:30
Yuxuan 'fishy' Wang dbdf13277d Fix typo in README (#39)
From de43f3afb6, both the code and the
commit message used singular form of expand_tag, but the example in the
README used the plural form of expand_tags. Based on that I assume the
singular form was the intention and the plural form in the README was a
typo (the plural form does not work because the code only checks for the
singular form env var).
2022-02-25 23:19:37 +05:30
Sinkerine c38eb07dea Fix the broken link in readme (#38) 2022-02-10 18:36:36 +05:30
Sinkerine de43f3afb6 Port the auto tag feature from docker plugin (#36)
* Port the auto tag feature from https://plugins.drone.io/drone-plugins/drone-docker

The logic is forked from https://github.com/drone-plugins/drone-docker code base
with necessary modification. I've tested it e2e for DockerHub on my Drone server
via this plugin image https://hub.docker.com/repository/docker/15cm/drone-kaniko,
for both tag pushes and commit pushes.

With this change the .drone.yml in this repo should work as intended.

Other changes:
- Rename the existing "auto tag" flags/code to "expand tag" for a less
misleading naming.
- ATTENTION: make a breaking change to set default value of "--tags" to empty.
Rationale is to expect most users to use the auto tagging feature. When power
users want to specify tags, they should always explicitly set tags instead of
being surprised by the default "latest" tag.

* Change how --auto-tag flag works with other flags

The --auto-tag has to be a breaking change. This commit limit the breaking
impact to the users who enable the flag. Behaviors of flag combination after
this commit:
* --auto-tag=false: No changes.
* --auto-tag=false,--expand-tag=true,tags=1.0.0:
  * Old behavior: Should not happen. --expand-tag didn't exist.
  * New Behavior: Build with [1,1.0,1.0.0] tags.
* --auto-tag=true
  * Old behavior: Build with the "latest" tag.
  * New behavior: Build with auto detected tags. Abort if auto detection failed.
* --auto-tag=true,tags=latest: same as "--auto-tag=true".
* --auto-tag=true,tags=1.0.0:
  * Old behavior: Build with [1,1.0,1.0.0] tags.
  * New behavior: Abort the build with an error message.
* --auto-tag=true,--expand-tag=true,tags=1.0.0: Abort the build with an error message.

Also added a test for the integration of the BUILD struct and the tagger
package, which is used by kaniko.go.

* Update readme to note that expand-tag and auto-tag don't support artifacts
2022-02-10 13:06:14 +05:30
Shubham Agrawal bebe65a6c2 Revert "Upgrade kaniko version to 1.7.0 (#37)"
This reverts commit 0a4b18dbcb.

Kaniko 1.7.0 version is unable to push latest tag on gcr:
https://github.com/GoogleContainerTools/kaniko/issues/1786#issuecomment-951369997
2022-02-08 17:16:47 +05:30
Shubham Agrawal 0a4b18dbcb Upgrade kaniko version to 1.7.0 (#37) 2022-02-07 19:55:05 +05:30
JimZhang d381ac6700 Fix "--cache-ttl" flag missing unit in duration (#35) 2022-02-07 19:13:29 +05:30
Kyle Lemons 39f3398dfe Make plugins/kaniko behave the same as plugins/kaniko-{ecr,gcr} by prefixing the registry to the repo (#31) 2022-01-20 00:41:45 +05:30
Shubham Agrawal 59e09c14de Add support for custom platform (#32) 2021-12-01 17:10:28 +05:30
18 changed files with 889 additions and 113 deletions
+106 -2
View File
@@ -4,7 +4,7 @@ name: default
steps:
- name: build
image: golang:1.17.2
image: golang:1.17.7
commands:
- go test ./...
- sh scripts/build.sh
@@ -60,6 +60,56 @@ steps:
exclude:
- pull_request
- name: docker-kaniko-v1-8
image: plugins/docker
settings:
repo: plugins/kaniko
auto_tag: true
auto_tag_suffix: linux-amd64-kaniko1.8.0
daemon_off: false
dockerfile: docker/docker/Dockerfile.linux.amd64.kaniko1.8.0
username:
from_secret: docker_username
password:
from_secret: docker_password
when:
event:
exclude:
- pull_request
- name: gcr-kaniko-v1-8
image: plugins/docker
settings:
repo: plugins/kaniko-gcr
auto_tag: true
auto_tag_suffix: linux-amd64-kaniko1.8.0
daemon_off: false
dockerfile: docker/gcr/Dockerfile.linux.amd64.kaniko1.8.0
username:
from_secret: docker_username
password:
from_secret: docker_password
when:
event:
exclude:
- pull_request
- name: ecr-kaniko-v1-8
image: plugins/docker
settings:
repo: plugins/kaniko-ecr
auto_tag: true
auto_tag_suffix: linux-amd64-kaniko1.8.0
daemon_off: false
dockerfile: docker/ecr/Dockerfile.linux.amd64.kaniko1.8.0
username:
from_secret: docker_username
password:
from_secret: docker_password
when:
event:
exclude:
- pull_request
---
kind: pipeline
type: docker
@@ -112,4 +162,58 @@ trigger:
- "refs/tags/**"
depends_on:
- default
- default
---
kind: pipeline
type: docker
name: notifications-docker-kaniko1-8
platform:
os: linux
arch: amd64
steps:
- name: manifest-docker
pull: always
image: plugins/manifest
settings:
auto_tag: true
ignore_missing: true
password:
from_secret: docker_password
spec: docker/docker/manifest-kaniko1.8.0.tmpl
username:
from_secret: docker_username
- name: manifest-gcr
pull: always
image: plugins/manifest
settings:
auto_tag: true
ignore_missing: true
password:
from_secret: docker_password
spec: docker/gcr/manifest-kaniko1.8.0.tmpl
username:
from_secret: docker_username
- name: manifest-ecr
pull: always
image: plugins/manifest
settings:
auto_tag: true
ignore_missing: true
password:
from_secret: docker_password
spec: docker/ecr/manifest-kaniko1.8.0.tmpl
username:
from_secret: docker_username
trigger:
ref:
- refs/heads/main
- "refs/tags/**"
depends_on:
- default
+49 -4
View File
@@ -39,6 +39,7 @@ docker build \
```
## Usage
### Manual Tagging
```console
docker run --rm \
@@ -52,14 +53,14 @@ docker run --rm \
plugins/kaniko:linux-amd64
```
### Automatic Tagging
With expanded tagging enabled, semantic versions can be passed to PLUGIN_TAGS directly for expansion.
With auto tagging enabled, semantic versions can be passed to PLUGIN_TAGS directly for expansion:
**Note**: this feature only works for build labels. Artifact labels are not supported.
```console
docker run --rm \
-e PLUGIN_TAGS=v1.2.3,latest \
-e PLUGIN_AUTO_TAG=true \
-e PLUGIN_EXPAND_TAG=true \
-v $(pwd):/drone \
-w /drone \
plugins/kaniko:linux-amd64
@@ -72,14 +73,58 @@ PLUGIN_TAGS=1,1.2,1.2.3,latest
This allows for passing `$DRONE_TAG` directly as a tag for repos that use [semver](https://semver.org) tags.
To avoid confusion between repo tags and image tags, `PLUGIN_AUTO_TAG` also recognizes a semantic version
To avoid confusion between repo tags and image tags, `PLUGIN_EXPAND_TAG` also recognizes a semantic version
without the `v` prefix. As such, the following is also equivalent to the above:
```console
docker run --rm \
-e PLUGIN_TAGS=1.2.3,latest \
-e PLUGIN_EXPAND_TAG=true \
-v $(pwd):/drone \
-w /drone \
plugins/kaniko:linux-amd64
```
### Auto Tagging
The [auto tag feature](https://plugins.drone.io/drone-plugins/drone-docker) of docker plugin is also supported.
When auto tagging is enabled, if any of the case is matched below, a docker build will be pushed with auto generated tags. Otherwise the docker build will be skipped.
**Note**: this feature only works for build labels. Artifact labels are not supported.
#### Git Tag Push:
```console
docker run --rm \
-e DRONE_COMMIT_REF=refs/tags/v1.2.3 \
-e PLUGIN_REPO=foo/bar \
-e PLUGIN_USERNAME=foo \
-e PLUGIN_PASSWORD=bar \
-e PLUGIN_AUTO_TAG=true \
-v $(pwd):/drone \
-w /drone \
plugins/kaniko:linux-amd64
```
Tags to push:
- 1.2.3
- 1.2
- 1
#### Git Commit Push in default branch:
```console
docker run --rm \
-e DRONE_COMMIT_REF=refs/heads/master \
-e DRONE_REPO_BRANCH=main \
-e PLUGIN_REPO=foo/bar \
-e PLUGIN_USERNAME=foo \
-e PLUGIN_PASSWORD=bar \
-e PLUGIN_AUTO_TAG=true \
-v $(pwd):/drone \
-w /drone \
plugins/kaniko:linux-amd64
```
Tags to push:
- latest
+71 -18
View File
@@ -5,6 +5,7 @@ import (
"fmt"
"io/ioutil"
"os"
"strings"
"github.com/joho/godotenv"
"github.com/pkg/errors"
@@ -57,6 +58,16 @@ func main() {
Value: ".",
EnvVar: "PLUGIN_CONTEXT",
},
cli.StringFlag{
Name: "drone-commit-ref",
Usage: "git commit ref passed by Drone",
EnvVar: "DRONE_COMMIT_REF",
},
cli.StringFlag{
Name: "drone-repo-branch",
Usage: "git repository default branch passed by Drone",
EnvVar: "DRONE_REPO_BRANCH",
},
cli.StringSliceFlag{
Name: "tags",
Usage: "build tags",
@@ -65,10 +76,20 @@ func main() {
FilePath: ".tags",
},
cli.BoolFlag{
Name: "auto_tag",
Name: "expand-tag",
Usage: "enable for semver tagging",
EnvVar: "PLUGIN_EXPAND_TAG",
},
cli.BoolFlag{
Name: "auto-tag",
Usage: "enable auto generation of build tags",
EnvVar: "PLUGIN_AUTO_TAG",
},
cli.StringFlag{
Name: "auto-tag-suffix",
Usage: "the suffix of auto build tags",
EnvVar: "PLUGIN_AUTO_TAG_SUFFIX",
},
cli.StringSliceFlag{
Name: "args",
Usage: "build args",
@@ -95,6 +116,11 @@ func main() {
Value: v1RegistryURL,
EnvVar: "PLUGIN_REGISTRY",
},
cli.StringSliceFlag{
Name: "registry-mirrors",
Usage: "docker registry mirrors",
EnvVar: "PLUGIN_REGISTRY_MIRRORS",
},
cli.StringFlag{
Name: "username",
Usage: "docker username",
@@ -145,6 +171,11 @@ func main() {
Usage: "Set this flag with value as oneof <panic|fatal|error|warn|info|debug|trace> to set the logging level for kaniko. Defaults to info.",
EnvVar: "PLUGIN_VERBOSITY",
},
cli.StringFlag{
Name: "platform",
Usage: "Allows to build with another default platform than the host, similarly to docker build --platform",
EnvVar: "PLUGIN_PLATFORM",
},
}
if err := app.Run(os.Args); err != nil {
@@ -165,26 +196,32 @@ func run(c *cli.Context) error {
plugin := kaniko.Plugin{
Build: kaniko.Build{
Dockerfile: c.String("dockerfile"),
Context: c.String("context"),
Tags: c.StringSlice("tags"),
AutoTag: c.Bool("auto_tag"),
Args: c.StringSlice("args"),
Target: c.String("target"),
Repo: c.String("repo"),
Labels: c.StringSlice("custom-labels"),
SkipTlsVerify: c.Bool("skip-tls-verify"),
SnapshotMode: c.String("snapshot-mode"),
EnableCache: c.Bool("enable-cache"),
CacheRepo: c.String("cache-repo"),
CacheTTL: c.Int("cache-ttl"),
DigestFile: defaultDigestFile,
NoPush: noPush,
Verbosity: c.String("verbosity"),
DroneCommitRef: c.String("drone-commit-ref"),
DroneRepoBranch: c.String("drone-repo-branch"),
Dockerfile: c.String("dockerfile"),
Context: c.String("context"),
Tags: c.StringSlice("tags"),
AutoTag: c.Bool("auto-tag"),
AutoTagSuffix: c.String("auto-tag-suffix"),
ExpandTag: c.Bool("expand-tag"),
Args: c.StringSlice("args"),
Target: c.String("target"),
Repo: buildRepo(c.String("registry"), c.String("repo")),
Mirrors: c.StringSlice("registry-mirrors"),
Labels: c.StringSlice("custom-labels"),
SkipTlsVerify: c.Bool("skip-tls-verify"),
SnapshotMode: c.String("snapshot-mode"),
EnableCache: c.Bool("enable-cache"),
CacheRepo: buildRepo(c.String("registry"), c.String("cache-repo")),
CacheTTL: c.Int("cache-ttl"),
DigestFile: defaultDigestFile,
NoPush: noPush,
Verbosity: c.String("verbosity"),
Platform: c.String("platform"),
},
Artifact: kaniko.Artifact{
Tags: c.StringSlice("tags"),
Repo: c.String("repo"),
Repo: buildRepo(c.String("registry"), c.String("repo")),
Registry: c.String("registry"),
ArtifactFile: c.String("artifact-file"),
RegistryType: artifact.Docker,
@@ -225,3 +262,19 @@ func createDockerCfgFile(username, password, registry string) error {
}
return nil
}
func buildRepo(registry, repo string) string {
if registry == "" {
// No custom registry, just return the repo name
return repo
}
// Trim off trailing slash to prevent double slash when combining with repo
registry = strings.TrimSuffix(registry, "/")
if strings.HasPrefix(repo, registry+"/") {
// Repo already includes the registry prefix
// For backward compatibility, we won't add the prefix again.
return repo
}
// Prefix the repo with the registry
return registry + "/" + repo
}
+37
View File
@@ -0,0 +1,37 @@
package main
import "testing"
func Test_buildRepo(t *testing.T) {
tests := []struct {
name string
registry string
repo string
want string
}{
{
name: "dockerhub",
repo: "golang",
want: "golang",
},
{
name: "internal",
registry: "artifactory.example.com",
repo: "service",
want: "artifactory.example.com/service",
},
{
name: "backward_compatibility",
registry: "artifactory.example.com",
repo: "artifactory.example.com/service",
want: "artifactory.example.com/service",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := buildRepo(tt.registry, tt.repo); got != tt.want {
t.Errorf("buildRepo(%q, %q) = %v, want %v", tt.registry, tt.repo, got, tt.want)
}
})
}
}
+52 -16
View File
@@ -71,6 +71,16 @@ func main() {
Value: ".",
EnvVar: "PLUGIN_CONTEXT",
},
cli.StringFlag{
Name: "drone-commit-ref",
Usage: "git commit ref passed by Drone",
EnvVar: "DRONE_COMMIT_REF",
},
cli.StringFlag{
Name: "drone-repo-branch",
Usage: "git repository default branch passed by Drone",
EnvVar: "DRONE_REPO_BRANCH",
},
cli.StringSliceFlag{
Name: "tags",
Usage: "build tags",
@@ -79,10 +89,20 @@ func main() {
FilePath: ".tags",
},
cli.BoolFlag{
Name: "auto_tag",
Name: "expand-tag",
Usage: "enable for semver tagging",
EnvVar: "PLUGIN_EXPAND_TAG",
},
cli.BoolFlag{
Name: "auto-tag",
Usage: "enable auto generation of build tags",
EnvVar: "PLUGIN_AUTO_TAG",
},
cli.StringFlag{
Name: "auto-tag-suffix",
Usage: "the suffix of auto build tags",
EnvVar: "PLUGIN_AUTO_TAG_SUFFIX",
},
cli.StringSliceFlag{
Name: "args",
Usage: "build args",
@@ -119,6 +139,11 @@ func main() {
Usage: "ECR registry",
EnvVar: "PLUGIN_REGISTRY",
},
cli.StringSliceFlag{
Name: "registry-mirrors",
Usage: "docker registry mirrors",
EnvVar: "PLUGIN_REGISTRY_MIRRORS",
},
cli.StringFlag{
Name: "access-key",
Usage: "ECR access key",
@@ -174,6 +199,11 @@ func main() {
Usage: "Set this flag with value as oneof <panic|fatal|error|warn|info|debug|trace> to set the logging level for kaniko. Defaults to info.",
EnvVar: "PLUGIN_VERBOSITY",
},
cli.StringFlag{
Name: "platform",
Usage: "Allows to build with another default platform than the host, similarly to docker build --platform",
EnvVar: "PLUGIN_PLATFORM",
},
}
if err := app.Run(os.Args); err != nil {
@@ -237,21 +267,27 @@ func run(c *cli.Context) error {
plugin := kaniko.Plugin{
Build: kaniko.Build{
Dockerfile: c.String("dockerfile"),
Context: c.String("context"),
Tags: c.StringSlice("tags"),
AutoTag: c.Bool("auto_tag"),
Args: c.StringSlice("args"),
Target: c.String("target"),
Repo: fmt.Sprintf("%s/%s", c.String("registry"), c.String("repo")),
Labels: c.StringSlice("custom-labels"),
SnapshotMode: c.String("snapshot-mode"),
EnableCache: c.Bool("enable-cache"),
CacheRepo: fmt.Sprintf("%s/%s", c.String("registry"), c.String("cache-repo")),
CacheTTL: c.Int("cache-ttl"),
DigestFile: defaultDigestFile,
NoPush: noPush,
Verbosity: c.String("verbosity"),
DroneCommitRef: c.String("drone-commit-ref"),
DroneRepoBranch: c.String("drone-repo-branch"),
Dockerfile: c.String("dockerfile"),
Context: c.String("context"),
Tags: c.StringSlice("tags"),
AutoTag: c.Bool("auto-tag"),
AutoTagSuffix: c.String("auto-tag-suffix"),
ExpandTag: c.Bool("expand-tag"),
Args: c.StringSlice("args"),
Target: c.String("target"),
Repo: fmt.Sprintf("%s/%s", c.String("registry"), c.String("repo")),
Mirrors: c.StringSlice("registry-mirrors"),
Labels: c.StringSlice("custom-labels"),
SnapshotMode: c.String("snapshot-mode"),
EnableCache: c.Bool("enable-cache"),
CacheRepo: fmt.Sprintf("%s/%s", c.String("registry"), c.String("cache-repo")),
CacheTTL: c.Int("cache-ttl"),
DigestFile: defaultDigestFile,
NoPush: noPush,
Verbosity: c.String("verbosity"),
Platform: c.String("platform"),
},
Artifact: kaniko.Artifact{
Tags: c.StringSlice("tags"),
+52 -16
View File
@@ -52,6 +52,16 @@ func main() {
Value: ".",
EnvVar: "PLUGIN_CONTEXT",
},
cli.StringFlag{
Name: "drone-commit-ref",
Usage: "git commit ref passed by Drone",
EnvVar: "DRONE_COMMIT_REF",
},
cli.StringFlag{
Name: "drone-repo-branch",
Usage: "git repository default branch passed by Drone",
EnvVar: "DRONE_REPO_BRANCH",
},
cli.StringSliceFlag{
Name: "tags",
Usage: "build tags",
@@ -60,10 +70,20 @@ func main() {
FilePath: ".tags",
},
cli.BoolFlag{
Name: "auto_tag",
Name: "expand-tag",
Usage: "enable for semver tagging",
EnvVar: "PLUGIN_EXPAND_TAG",
},
cli.BoolFlag{
Name: "auto-tag",
Usage: "enable auto generation of build tags",
EnvVar: "PLUGIN_AUTO_TAG",
},
cli.StringFlag{
Name: "auto-tag-suffix",
Usage: "the suffix of auto build tags",
EnvVar: "PLUGIN_AUTO_TAG_SUFFIX",
},
cli.StringSliceFlag{
Name: "args",
Usage: "build args",
@@ -90,6 +110,11 @@ func main() {
Value: "gcr.io",
EnvVar: "PLUGIN_REGISTRY",
},
cli.StringSliceFlag{
Name: "registry-mirrors",
Usage: "docker registry mirrors",
EnvVar: "PLUGIN_REGISTRY_MIRRORS",
},
cli.StringFlag{
Name: "json-key",
Usage: "docker username",
@@ -130,6 +155,11 @@ func main() {
Usage: "Set this flag as --verbosity=<panic|fatal|error|warn|info|debug|trace> to set the logging level for kaniko. Defaults to info.",
EnvVar: "PLUGIN_VERBOSITY",
},
cli.StringFlag{
Name: "platform",
Usage: "Allows to build with another default platform than the host, similarly to docker build --platform",
EnvVar: "PLUGIN_PLATFORM",
},
}
if err := app.Run(os.Args); err != nil {
@@ -152,21 +182,27 @@ func run(c *cli.Context) error {
plugin := kaniko.Plugin{
Build: kaniko.Build{
Dockerfile: c.String("dockerfile"),
Context: c.String("context"),
Tags: c.StringSlice("tags"),
AutoTag: c.Bool("auto_tag"),
Args: c.StringSlice("args"),
Target: c.String("target"),
Repo: fmt.Sprintf("%s/%s", c.String("registry"), c.String("repo")),
Labels: c.StringSlice("custom-labels"),
SnapshotMode: c.String("snapshot-mode"),
EnableCache: c.Bool("enable-cache"),
CacheRepo: fmt.Sprintf("%s/%s", c.String("registry"), c.String("cache-repo")),
CacheTTL: c.Int("cache-ttl"),
DigestFile: defaultDigestFile,
NoPush: noPush,
Verbosity: c.String("verbosity"),
DroneCommitRef: c.String("drone-commit-ref"),
DroneRepoBranch: c.String("drone-repo-branch"),
Dockerfile: c.String("dockerfile"),
Context: c.String("context"),
Tags: c.StringSlice("tags"),
AutoTag: c.Bool("auto-tag"),
AutoTagSuffix: c.String("auto-tag-suffix"),
ExpandTag: c.Bool("expand-tag"),
Args: c.StringSlice("args"),
Target: c.String("target"),
Repo: fmt.Sprintf("%s/%s", c.String("registry"), c.String("repo")),
Mirrors: c.StringSlice("registry-mirrors"),
Labels: c.StringSlice("custom-labels"),
SnapshotMode: c.String("snapshot-mode"),
EnableCache: c.Bool("enable-cache"),
CacheRepo: fmt.Sprintf("%s/%s", c.String("registry"), c.String("cache-repo")),
CacheTTL: c.Int("cache-ttl"),
DigestFile: defaultDigestFile,
NoPush: noPush,
Verbosity: c.String("verbosity"),
Platform: c.String("platform"),
},
Artifact: kaniko.Artifact{
Tags: c.StringSlice("tags"),
@@ -0,0 +1,4 @@
FROM gcr.io/kaniko-project/executor:v1.8.0
ADD release/linux/amd64/kaniko-docker /kaniko/
ENTRYPOINT ["/kaniko/kaniko-docker"]
+13
View File
@@ -0,0 +1,13 @@
image: plugins/kaniko:{{#if build.tag}}{{trimPrefix "v" build.tag}}-kaniko1.8.0{{else}}latest-kaniko1.8.0{{/if}}
{{#if build.tags}}
tags:
{{#each build.tags}}
- {{this}}
{{/each}}
{{/if}}
manifests:
-
image: plugins/kaniko:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}linux-amd64-kaniko1.8.0
platform:
architecture: amd64
os: linux
@@ -0,0 +1,4 @@
FROM gcr.io/kaniko-project/executor:v1.8.0
ADD release/linux/amd64/kaniko-ecr /kaniko/
ENTRYPOINT ["/kaniko/kaniko-ecr"]
+13
View File
@@ -0,0 +1,13 @@
image: plugins/ecr:{{#if build.tag}}{{trimPrefix "v" build.tag}}-kaniko1.8.0{{else}}latest-kaniko1.8.0{{/if}}
{{#if build.tags}}
tags:
{{#each build.tags}}
- {{this}}
{{/each}}
{{/if}}
manifests:
-
image: plugins/ecr:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}linux-amd64-kaniko1.8.0
platform:
architecture: amd64
os: linux
@@ -0,0 +1,4 @@
FROM gcr.io/kaniko-project/executor:v1.8.0
ADD release/linux/amd64/kaniko-gcr /kaniko/
ENTRYPOINT ["/kaniko/kaniko-gcr"]
+13
View File
@@ -0,0 +1,13 @@
image: plugins/gcr:{{#if build.tag}}{{trimPrefix "v" build.tag}}-kaniko1.8.0{{else}}latest-kaniko1.8.0{{/if}}
{{#if build.tags}}
tags:
{{#each build.tags}}
- {{this}}
{{/each}}
{{/if}}
manifests:
-
image: plugins/gcr:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}linux-amd64-kaniko1.8.0
platform:
architecture: amd64
os: linux
+1
View File
@@ -6,6 +6,7 @@ require (
github.com/aws/aws-sdk-go-v2/service/ecr v1.4.3
github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.4.3
github.com/aws/smithy-go v1.7.0
github.com/coreos/go-semver v0.3.0
github.com/google/go-cmp v0.5.6
github.com/joho/godotenv v1.3.0
github.com/pkg/errors v0.9.1
+2
View File
@@ -21,6 +21,8 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.6.2 h1:l504GWCoQi1Pk68vSUFGLmDIEMzRf
github.com/aws/aws-sdk-go-v2/service/sts v1.6.2/go.mod h1:RBhoMJB8yFToaCnbe0jNq5Dcdy0jp6LhHqg55rjClkM=
github.com/aws/smithy-go v1.7.0 h1:+cLHMRrDZvQ4wk+KuQ9yH6eEg6KZEJ9RI2IkDqnygCg=
github.com/aws/smithy-go v1.7.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E=
github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+72 -22
View File
@@ -8,28 +8,35 @@ import (
"strings"
"github.com/drone/drone-kaniko/pkg/artifact"
"github.com/drone/drone-kaniko/pkg/tagger"
"golang.org/x/mod/semver"
)
type (
// Build defines Docker build parameters.
Build struct {
Dockerfile string // Docker build Dockerfile
Context string // Docker build context
Tags []string // Docker build tags
AutoTag bool // Set this to create semver-tagged labels
Args []string // Docker build args
Target string // Docker build target
Repo string // Docker build repository
Labels []string // Label map
SkipTlsVerify bool // Docker skip tls certificate verify for registry
SnapshotMode string // Kaniko snapshot mode
EnableCache bool // Whether to enable kaniko cache
CacheRepo string // Remote repository that will be used to store cached layers
CacheTTL int // Cache timeout in hours
DigestFile string // Digest file location
NoPush bool // Set this flag if you only want to build the image, without pushing to a registry
Verbosity string // Log level
DroneCommitRef string // Drone git commit reference
DroneRepoBranch string // Drone repo branch
Dockerfile string // Docker build Dockerfile
Context string // Docker build context
Tags []string // Docker build tags
AutoTag bool // Set this to auto detect tags from git commits and semver-tagged labels
AutoTagSuffix string // Suffix to append to the auto detect tags
ExpandTag bool // Set this to expand the `Tags` into semver-tagged labels
Args []string // Docker build args
Target string // Docker build target
Repo string // Docker build repository
Mirrors []string // Docker repository mirrors
Labels []string // Label map
SkipTlsVerify bool // Docker skip tls certificate verify for registry
SnapshotMode string // Kaniko snapshot mode
EnableCache bool // Whether to enable kaniko cache
CacheRepo string // Remote repository that will be used to store cached layers
CacheTTL int // Cache timeout in hours
DigestFile string // Digest file location
NoPush bool // Set this flag if you only want to build the image, without pushing to a registry
Verbosity string // Log level
Platform string // Allows to build with another default platform than the host, similarly to docker build --platform
}
// Artifact defines content of artifact file
@@ -48,7 +55,7 @@ type (
}
)
// labelsForTag returns the labels to use for the given tag, subject to the value of AutoTag.
// labelsForTag returns the labels to use for the given tag, subject to the value of ExpandTag.
//
// Build information (e.g. +linux_amd64) is carried through to all labels.
// Pre-release information (e.g. -rc1) suppresses major and major+minor auto-labels.
@@ -65,8 +72,8 @@ func (b Build) labelsForTag(tag string) (labels []string) {
semverTag = withV
}
// Pass through tags if auto-tag is not set, or if the tag is not a semantic version
if !b.AutoTag || !semver.IsValid(semverTag) {
// Pass through tags if expand-tag is not set, or if the tag is not a semantic version
if !b.ExpandTag || !semver.IsValid(semverTag) {
return []string{tag}
}
tag = semverTag
@@ -89,6 +96,30 @@ func (b Build) labelsForTag(tag string) (labels []string) {
}
}
// Returns the auto detected tags. See the AutoTag section of
// https://plugins.drone.io/drone-plugins/drone-docker/ for more info.
func (b Build) AutoTags() (tags []string, err error) {
if len(b.Tags) > 1 || len(b.Tags) == 1 && b.Tags[0] != "latest" {
err = fmt.Errorf("The auto-tag flag does not work with user provided tags %s", b.Tags)
return
}
// We have tried the best to prevent enabling auto-tag and passing in
// user specified at the same time. Starts to auto detect tags.
// Note: passing in a "latest" tag with auto-tag enabled won't trigger the
// early returns above, because we cannot tell if the tag is provided by
// the default value or by the users.
commitRef := b.DroneCommitRef
if !tagger.UseAutoTag(commitRef, b.DroneRepoBranch) {
err = fmt.Errorf("Could not auto detect the tag. Skipping automated docker build for commit %s", commitRef)
return
}
tags, err = tagger.AutoTagsSuffix(commitRef, b.AutoTagSuffix)
if err != nil {
err = fmt.Errorf("Invalid semantic version when auto detecting the tag. Skipping automated docker build for %s.", commitRef)
}
return
}
// Exec executes the plugin step
func (p Plugin) Exec() error {
if !p.Build.NoPush && p.Build.Repo == "" {
@@ -99,6 +130,18 @@ func (p Plugin) Exec() error {
return fmt.Errorf("dockerfile does not exist at path: %s", p.Build.Dockerfile)
}
var tags = p.Build.Tags
if p.Build.AutoTag && p.Build.ExpandTag {
return fmt.Errorf("The auto-tag flag conflicts with the expand-tag flag")
}
if p.Build.AutoTag {
var err error
tags, err = p.Build.AutoTags()
if err != nil {
return err
}
}
cmdArgs := []string{
fmt.Sprintf("--dockerfile=%s", p.Build.Dockerfile),
fmt.Sprintf("--context=dir://%s", p.Build.Context),
@@ -106,7 +149,7 @@ func (p Plugin) Exec() error {
// Set the destination repository
if !p.Build.NoPush {
for _, tag := range p.Build.Tags {
for _, tag := range tags {
for _, label := range p.Build.labelsForTag(tag) {
cmdArgs = append(cmdArgs, fmt.Sprintf("--destination=%s:%s", p.Build.Repo, label))
}
@@ -120,7 +163,10 @@ func (p Plugin) Exec() error {
for _, label := range p.Build.Labels {
cmdArgs = append(cmdArgs, fmt.Sprintf("--label=%s", label))
}
// Set repository mirrors
for _, mirror := range p.Build.Mirrors {
cmdArgs = append(cmdArgs, fmt.Sprintf("--registry-mirror=%s", mirror))
}
if p.Build.Target != "" {
cmdArgs = append(cmdArgs, fmt.Sprintf("--target=%s", p.Build.Target))
}
@@ -142,7 +188,7 @@ func (p Plugin) Exec() error {
}
if p.Build.CacheTTL != 0 {
cmdArgs = append(cmdArgs, fmt.Sprintf("--cache-ttl=%d", p.Build.CacheTTL))
cmdArgs = append(cmdArgs, fmt.Sprintf("--cache-ttl=%dh", p.Build.CacheTTL))
}
if p.Build.DigestFile != "" {
@@ -157,6 +203,10 @@ func (p Plugin) Exec() error {
cmdArgs = append(cmdArgs, fmt.Sprintf("--verbosity=%s", p.Build.Verbosity))
}
if p.Build.Platform != "" {
cmdArgs = append(cmdArgs, fmt.Sprintf("--customPlatform=%s", p.Build.Platform))
}
cmd := exec.Command("/kaniko/executor", cmdArgs...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
+102 -35
View File
@@ -8,67 +8,134 @@ import (
func TestBuild_labelsForTag(t *testing.T) {
tests := []struct {
name string
tag string
autoTags []string
name string
tag string
expandTags []string
}{
{
name: "semver",
tag: "v1.2.3",
autoTags: []string{"1", "1.2", "1.2.3"},
name: "semver",
tag: "v1.2.3",
expandTags: []string{"1", "1.2", "1.2.3"},
},
{
name: "no_patch",
tag: "v1.2",
autoTags: []string{"1", "1.2", "1.2.0"},
name: "no_patch",
tag: "v1.2",
expandTags: []string{"1", "1.2", "1.2.0"},
},
{
name: "only_major",
tag: "v1",
autoTags: []string{"1", "1.0", "1.0.0"},
name: "only_major",
tag: "v1",
expandTags: []string{"1", "1.0", "1.0.0"},
},
{
name: "full_with_build",
tag: "v1.2.3+build-info",
autoTags: []string{"1+build-info", "1.2+build-info", "1.2.3+build-info"},
name: "full_with_build",
tag: "v1.2.3+build-info",
expandTags: []string{"1+build-info", "1.2+build-info", "1.2.3+build-info"},
},
{
name: "build_with_underscores",
tag: "v1.2.3+linux_amd64",
autoTags: []string{"1+linux-amd64", "1.2+linux-amd64", "1.2.3+linux-amd64"},
name: "build_with_underscores",
tag: "v1.2.3+linux_amd64",
expandTags: []string{"1+linux-amd64", "1.2+linux-amd64", "1.2.3+linux-amd64"},
},
{
name: "prerelease",
tag: "v1.2.3-rc1",
autoTags: []string{"1.2.3-rc1"},
name: "prerelease",
tag: "v1.2.3-rc1",
expandTags: []string{"1.2.3-rc1"},
},
{
name: "prerelease_with_build",
tag: "v1.2.3-rc1+bld",
autoTags: []string{"1.2.3-rc1+bld"},
name: "prerelease_with_build",
tag: "v1.2.3-rc1+bld",
expandTags: []string{"1.2.3-rc1+bld"},
},
{
name: "invalid_build",
tag: "v1+bld", // can only include build detail with all three elements
autoTags: []string{"v1+bld"},
name: "invalid_build",
tag: "v1+bld", // can only include build detail with all three elements
expandTags: []string{"v1+bld"},
},
{
name: "accidental_non_semver",
tag: "1.2.3",
autoTags: []string{"1", "1.2", "1.2.3"},
name: "accidental_non_semver",
tag: "1.2.3",
expandTags: []string{"1", "1.2", "1.2.3"},
},
{
name: "non_semver",
tag: "latest",
autoTags: []string{"latest"},
name: "non_semver",
tag: "latest",
expandTags: []string{"latest"},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tags := Build{AutoTag: true}.labelsForTag(tt.tag)
if got, want := tags, tt.autoTags; !cmp.Equal(got, want) {
tags := Build{ExpandTag: true}.labelsForTag(tt.tag)
if got, want := tags, tt.expandTags; !cmp.Equal(got, want) {
t.Errorf("tagsFor(%q) = %q, want %q", tt.tag, got, want)
}
})
}
}
func TestBuild_AutoTags(t *testing.T) {
tests := []struct {
name string
repoBranch string
commitRef string
autoTagSuffix string
expectedTags []string
}{
{
name: "commit push",
repoBranch: "master",
commitRef: "refs/heads/master",
autoTagSuffix: "",
expectedTags: []string{"latest"},
},
{
name: "tag push",
repoBranch: "master",
commitRef: "refs/tags/v1.0.0",
autoTagSuffix: "",
expectedTags: []string{
"1",
"1.0",
"1.0.0",
},
},
{
name: "tag push",
repoBranch: "master",
commitRef: "refs/tags/v1.0.0",
autoTagSuffix: "linux-amd64",
expectedTags: []string{
"1-linux-amd64",
"1.0-linux-amd64",
"1.0.0-linux-amd64",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
b := Build{DroneCommitRef: tt.commitRef, DroneRepoBranch: tt.repoBranch, AutoTag: true}
if tt.autoTagSuffix != "" {
b.AutoTagSuffix = tt.autoTagSuffix
}
tags, err := b.AutoTags()
if err != nil {
t.Errorf("Unexpected err %q", err)
}
if got, want := tags, tt.expectedTags; !cmp.Equal(got, want) {
t.Errorf("auto detected tags = %q, wanted = %q", got, want)
}
})
}
t.Run("auto-tag cannot be enabled with user provided tags", func(t *testing.T) {
b := Build{
DroneCommitRef: "refs/tags/v1.0.0",
DroneRepoBranch: "master",
AutoTag: true,
Tags: []string{"v1"},
}
_, err := b.AutoTags()
if err == nil {
t.Errorf("Expect error for invalid flags")
}
})
}
+95
View File
@@ -0,0 +1,95 @@
// A fork of https://github.com/drone-plugins/drone-docker/blob/master/tags.go
package tagger
import (
"fmt"
"strings"
"github.com/coreos/go-semver/semver"
)
// AutoTagsSuffix returns a set of default suggested tags
// based on the commit ref with an attached suffix.
func AutoTagsSuffix(ref, suffix string) ([]string, error) {
tags, err := AutoTags(ref)
if err != nil {
return nil, err
}
if len(suffix) == 0 {
return tags, nil
}
for i, tag := range tags {
if tag == "latest" {
tags[i] = suffix
} else {
tags[i] = fmt.Sprintf("%s-%s", tag, suffix)
}
}
return tags, nil
}
func splitOff(input string, delim string) string {
parts := strings.SplitN(input, delim, 2)
if len(parts) == 2 {
return parts[0]
}
return input
}
// AutoTags returns a set of default suggested tags based on
// the commit ref.
func AutoTags(ref string) ([]string, error) {
if !strings.HasPrefix(ref, "refs/tags/") {
return []string{"latest"}, nil
}
v := stripTagPrefix(ref)
version, err := semver.NewVersion(v)
if err != nil {
return []string{"latest"}, err
}
if version.PreRelease != "" || version.Metadata != "" {
return []string{
version.String(),
}, nil
}
v = stripTagPrefix(ref)
v = splitOff(splitOff(v, "+"), "-")
dotParts := strings.SplitN(v, ".", 3)
if version.Major == 0 {
return []string{
fmt.Sprintf("%0*d.%0*d", len(dotParts[0]), version.Major, len(dotParts[1]), version.Minor),
fmt.Sprintf("%0*d.%0*d.%0*d", len(dotParts[0]), version.Major, len(dotParts[1]), version.Minor, len(dotParts[2]), version.Patch),
}, nil
}
return []string{
fmt.Sprintf("%0*d", len(dotParts[0]), version.Major),
fmt.Sprintf("%0*d.%0*d", len(dotParts[0]), version.Major, len(dotParts[1]), version.Minor),
fmt.Sprintf("%0*d.%0*d.%0*d", len(dotParts[0]), version.Major, len(dotParts[1]), version.Minor, len(dotParts[2]), version.Patch),
}, nil
}
// UseAutoTag for keep only default branch for latest tag.
func UseAutoTag(ref, defaultBranch string) bool {
if strings.HasPrefix(ref, "refs/tags/") {
return true
}
if stripHeadPrefix(ref) == defaultBranch {
return true
}
return false
}
func stripHeadPrefix(ref string) string {
return strings.TrimPrefix(ref, "refs/heads/")
}
func stripTagPrefix(ref string) string {
ref = strings.TrimPrefix(ref, "refs/tags/")
ref = strings.TrimPrefix(ref, "v")
return ref
}
+199
View File
@@ -0,0 +1,199 @@
// A fork of https://github.com/drone-plugins/drone-docker/blob/master/tags_test.go
package tagger
import (
"reflect"
"testing"
)
func Test_stripTagPrefix(t *testing.T) {
var tests = []struct {
Before string
After string
}{
{"refs/tags/1.0.0", "1.0.0"},
{"refs/tags/v1.0.0", "1.0.0"},
{"v1.0.0", "1.0.0"},
}
for _, test := range tests {
got, want := stripTagPrefix(test.Before), test.After
if got != want {
t.Errorf("Got tag %s, want %s", got, want)
}
}
}
func TestAutoTags(t *testing.T) {
var tests = []struct {
Before string
After []string
}{
{"", []string{"latest"}},
{"refs/heads/master", []string{"latest"}},
{"refs/tags/0.9.0", []string{"0.9", "0.9.0"}},
{"refs/tags/1.0.0", []string{"1", "1.0", "1.0.0"}},
{"refs/tags/v1.0.0", []string{"1", "1.0", "1.0.0"}},
{"refs/tags/v1.0.0-alpha.1", []string{"1.0.0-alpha.1"}},
}
for _, test := range tests {
tags, err := AutoTags(test.Before)
if err != nil {
t.Error(err)
continue
}
got, want := tags, test.After
if !reflect.DeepEqual(got, want) {
t.Errorf("Got tag %v, want %v", got, want)
}
}
}
func TestAutoTagsError(t *testing.T) {
var tests = []string{
"refs/tags/x1.0.0",
"refs/tags/20190203",
}
for _, test := range tests {
_, err := AutoTags(test)
if err == nil {
t.Errorf("Expect tag error for %s", test)
}
}
}
func TestAutoTagsSuffix(t *testing.T) {
var tests = []struct {
Before string
Suffix string
After []string
}{
// without suffix
{
After: []string{"latest"},
},
{
Before: "refs/tags/v1.0.0",
After: []string{
"1",
"1.0",
"1.0.0",
},
},
// with suffix
{
Suffix: "linux-amd64",
After: []string{"linux-amd64"},
},
{
Before: "refs/tags/v1.0.0",
Suffix: "linux-amd64",
After: []string{
"1-linux-amd64",
"1.0-linux-amd64",
"1.0.0-linux-amd64",
},
},
{
Suffix: "nanoserver",
After: []string{"nanoserver"},
},
{
Before: "refs/tags/v1.9.2",
Suffix: "nanoserver",
After: []string{
"1-nanoserver",
"1.9-nanoserver",
"1.9.2-nanoserver",
},
},
{
Before: "refs/tags/v18.06.0",
Suffix: "nanoserver",
After: []string{
"18-nanoserver",
"18.06-nanoserver",
"18.06.0-nanoserver",
},
},
}
for _, test := range tests {
tag, err := AutoTagsSuffix(test.Before, test.Suffix)
if err != nil {
t.Error(err)
continue
}
got, want := tag, test.After
if !reflect.DeepEqual(got, want) {
t.Errorf("Got tag %v, want %v", got, want)
}
}
}
func Test_stripHeadPrefix(t *testing.T) {
type args struct {
ref string
}
tests := []struct {
args args
want string
}{
{
args: args{
ref: "refs/heads/master",
},
want: "master",
},
}
for _, tt := range tests {
if got := stripHeadPrefix(tt.args.ref); got != tt.want {
t.Errorf("stripHeadPrefix() = %v, want %v", got, tt.want)
}
}
}
func TestUseAutoTag(t *testing.T) {
type args struct {
ref string
defaultBranch string
}
tests := []struct {
name string
args args
want bool
}{
{
name: "latest tag for default branch",
args: args{
ref: "refs/heads/master",
defaultBranch: "master",
},
want: true,
},
{
name: "build from tags",
args: args{
ref: "refs/tags/v1.0.0",
defaultBranch: "master",
},
want: true,
},
{
name: "skip build for not default branch",
args: args{
ref: "refs/heads/develop",
defaultBranch: "master",
},
want: false,
},
}
for _, tt := range tests {
if got := UseAutoTag(tt.args.ref, tt.args.defaultBranch); got != tt.want {
t.Errorf("%q. UseAutoTag() = %v, want %v", tt.name, got, tt.want)
}
}
}