diff --git a/.drone.star b/.drone.star new file mode 100644 index 0000000..c218d83 --- /dev/null +++ b/.drone.star @@ -0,0 +1,105 @@ +# go version +go = "golang:1.13" + +# docker repository +repo = "drone/drone-runner-docker" + +def main(ctx): + return [ + pipeline_linux(), + pipeline_windows("1903"), + pipeline_windows("1809"), + pipeline_manifest(), + # manifest + ] + + +def pipeline_linux(): + return { + "kind": "pipeline", + "type": "docker", + "name": "linux", + "steps": [ + test, + build, + publish("arm"), + publish("arm64"), + publish("amd64"), + ] + } + +def pipeline_windows(version): + return { + "kind": "pipeline", + "type": "ssh", + "name": "windows_%s" % version, + "server": { + + }, + "platform": { + "os": "windows", + }, + "steps": [ + "sh scripts/ci_%s.ps1" % version, + ], + } + +def pipeline_manifest(): + return [ + "kind": "pipeline", + "type": "docker", + "name": "linux", + "steps": [ + { + + } + ] + ] + +# publish creates a docker publish step. +def publish(arch): + return { + "name": "publish_%s" % arch, + "image": "plugins/docker", + "pull": "if-not-exists", + "settings": { + "auto_tag": "true", + "auto_tag_suffix": "linux-%s" % arch, + "dockerfile": "docker/Dockerfile.linux.%s" % arch, + "repo": repo, + }, + "when": { + "event": [ "push", "tag" ] + } + } + +# test defines a test step that downloads +# dependencies and tests the packages. +test = { + "name": "test", + "image": go, + "volumes": mounts, + "commands": [ + "go test -v ./...", + ], +} + +# build defines a build step that compiles +# the binaries. +build = { + "name": "build", + "image": go, + "volumes": mounts, + "commands": [ + "sh scripts/build.sh", + ], + "when": { + "event": [ "push", "tag" ] + } +} + +# mount points shared by all steps. +mounts = [{ + "name": "go", + "path": "/go", +}] diff --git a/.drone.yml b/.drone.yml index 12b295a..04c568a 100644 --- a/.drone.yml +++ b/.drone.yml @@ -26,7 +26,7 @@ steps: - push - tag -- name: publish +- name: publish_amd64 image: plugins/docker pull: if-not-exists settings: @@ -43,6 +43,40 @@ steps: - refs/heads/master - refs/tags/* +- name: publish_arm + image: plugins/docker + pull: if-not-exists + settings: + repo: drone/drone-runner-docker + auto_tag: true + auto_tag_suffix: linux-arm + dockerfile: docker/Dockerfile.linux.arm + username: + from_secret: docker_username + password: + from_secret: docker_password + when: + ref: + - refs/heads/master + - refs/tags/* + +- name: publish_arm64 + image: plugins/docker + pull: if-not-exists + settings: + repo: drone/drone-runner-docker + auto_tag: true + auto_tag_suffix: linux-arm + dockerfile: docker/Dockerfile.linux.arm64 + username: + from_secret: docker_username + password: + from_secret: docker_password + when: + ref: + - refs/heads/master + - refs/tags/* + volumes: - name: go temp: {} diff --git a/.github/code_of_conduct.md b/.github/code_of_conduct.md deleted file mode 100644 index 7134070..0000000 --- a/.github/code_of_conduct.md +++ /dev/null @@ -1,73 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to making participation in our project and -our community a harassment-free experience for everyone, regardless of age, body -size, disability, ethnicity, gender identity and expression, level of experience, -education, socio-economic status, nationality, personal appearance, race, -religion, or sexual identity and orientation. - -## Our Standards - -Examples of behavior that contributes to creating a positive environment -include: - -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery and unwelcome sexual attention or - advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic - address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Our Responsibilities - -Project maintainers are responsible for clarifying the standards of acceptable -behavior and are expected to take appropriate and fair corrective action in -response to any instances of unacceptable behavior. - -Project maintainers have the right and responsibility to remove, edit, or -reject comments, commits, code, wiki edits, issues, and other contributions -that are not aligned to this Code of Conduct, or to ban temporarily or -permanently any contributor for other behaviors that they deem inappropriate, -threatening, offensive, or harmful. - -## Scope - -This Code of Conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. Examples of -representing a project or community include using an official project e-mail -address, posting via an official social media account, or acting as an appointed -representative at an online or offline event. Representation of a project may be -further defined and clarified by project maintainers. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at conduct@drone.io. All -complaints will be reviewed and investigated and will result in a response that -is deemed necessary and appropriate to the circumstances. The project team is -obligated to maintain confidentiality with regard to the reporter of an incident. -Further details of specific enforcement policies may be posted separately. - -Project maintainers who do not follow or enforce the Code of Conduct in good -faith may face temporary or permanent repercussions as determined by other -members of the project's leadership. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, -available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html - -[homepage]: https://www.contributor-covenant.org diff --git a/command/compile.go b/command/compile.go index 50f4e82..69a8de3 100644 --- a/command/compile.go +++ b/command/compile.go @@ -12,7 +12,6 @@ import ( "strings" "github.com/drone-runners/drone-runner-docker/command/internal" - "github.com/drone-runners/drone-runner-docker/engine" "github.com/drone-runners/drone-runner-docker/engine/compiler" "github.com/drone-runners/drone-runner-docker/engine/linter" "github.com/drone-runners/drone-runner-docker/engine/resource" @@ -109,6 +108,14 @@ func (c *compileCommand) run(*kingpin.ParseContext) error { registry.File(c.Config), ), } + + // when running a build locally cloning is always + // disabled in favor of mounting the source code + // from the current working directory. + if c.Clone == false { + comp.Mount, _ = os.Getwd() + } + args := compiler.Args{ Pipeline: resource, Manifest: manifest, @@ -120,28 +127,6 @@ func (c *compileCommand) run(*kingpin.ParseContext) error { } spec := comp.Compile(nocontext, args) - // when running a build locally cloning is always - // disabled in favor of mounting the source code - // from the current working directory. - if c.Clone == false { - pwd, _ := os.Getwd() - for _, volume := range spec.Volumes { - if volume.EmptyDir != nil && volume.EmptyDir.Name == "_workspace" { - volume.HostPath = &engine.VolumeHostPath{ - ID: volume.EmptyDir.ID, - Name: volume.EmptyDir.Name, - Path: pwd, - } - volume.EmptyDir = nil - } - } - for _, step := range spec.Steps { - if step.Name == "clone" { - step.RunPolicy = engine.RunNever - } - } - } - // encode the pipeline in json format and print to the // console for inspection. enc := json.NewEncoder(os.Stdout) diff --git a/command/exec.go b/command/exec.go index 366617e..3c22489 100644 --- a/command/exec.go +++ b/command/exec.go @@ -128,6 +128,14 @@ func (c *execCommand) run(*kingpin.ParseContext) error { registry.File(c.Config), ), } + + // when running a build locally cloning is always + // disabled in favor of mounting the source code + // from the current working directory. + if c.Clone == false { + comp.Mount, _ = os.Getwd() + } + args := compiler.Args{ Pipeline: resource, Manifest: manifest, diff --git a/engine/compiler/compiler.go b/engine/compiler/compiler.go index f204f9a..50a2456 100644 --- a/engine/compiler/compiler.go +++ b/engine/compiler/compiler.go @@ -126,6 +126,10 @@ type Compiler struct { // Registry returns a list of registry credentials that can be // used to pull private container images. Registry registry.Provider + + // Mount is an optional field that overrides the default + // workspace volume and mounts to the host path + Mount string } // Compile compiles the configuration file. @@ -135,10 +139,12 @@ func (c *Compiler) Compile(ctx context.Context, args Args) *engine.Spec { // create the workspace paths base, path, full := createWorkspace(args.Pipeline) - // create the workspace mount - mount := &engine.VolumeMount{ - Name: "_workspace", - Path: base, + // if the source code is mounted from the host, the + // target mount path inside the container must be the + // full workspace path. + if c.Mount != "" { + base = full + path = "" } // create system labels @@ -151,11 +157,32 @@ func (c *Compiler) Compile(ctx context.Context, args Args) *engine.Spec { labels.WithTimeout(args.Repo), ) + // create the workspace mount + mount := &engine.VolumeMount{ + Name: "_workspace", + Path: base, + } + // create the workspace volume - volume := &engine.VolumeEmptyDir{ - ID: random(), - Name: mount.Name, - Labels: labels, + volume := &engine.Volume{ + EmptyDir: &engine.VolumeEmptyDir{ + ID: random(), + Name: mount.Name, + Labels: labels, + }, + } + + // if the repository is mounted from a local volume, + // we should replace the data volume with a host machine + // volume declaration. + if c.Mount != "" { + volume.EmptyDir = nil + volume.HostPath = &engine.VolumeHostPath{ + ID: random(), + Name: mount.Name, + Path: c.Mount, + Labels: labels, + } } spec := &engine.Spec{ @@ -169,9 +196,7 @@ func (c *Compiler) Compile(ctx context.Context, args Args) *engine.Spec { Variant: args.Pipeline.Platform.Variant, Version: args.Pipeline.Platform.Version, }, - Volumes: []*engine.Volume{ - {EmptyDir: volume}, - }, + Volumes: []*engine.Volume{volume}, } // create the default environment variables. @@ -195,8 +220,7 @@ func (c *Compiler) Compile(ctx context.Context, args Args) *engine.Spec { }), ) - // create docker reference variables - envs["DRONE_DOCKER_VOLUME_ID"] = volume.ID + // create network reference variables envs["DRONE_DOCKER_NETWORK_ID"] = spec.Network.ID // create the workspace variables @@ -204,6 +228,13 @@ func (c *Compiler) Compile(ctx context.Context, args Args) *engine.Spec { envs["DRONE_WORKSPACE_BASE"] = base envs["DRONE_WORKSPACE_PATH"] = path + // create volume reference variables + if volume.EmptyDir != nil { + envs["DRONE_DOCKER_VOLUME_ID"] = volume.EmptyDir.ID + } else { + envs["DRONE_DOCKER_VOLUME_PATH"] = volume.HostPath.Path + } + // create the netrc environment variables if args.Netrc != nil && args.Netrc.Machine != "" { envs["DRONE_NETRC_MACHINE"] = args.Netrc.Machine @@ -237,6 +268,12 @@ func (c *Compiler) Compile(ctx context.Context, args Args) *engine.Spec { step.Labels = labels step.Volumes = append(step.Volumes, mount) spec.Steps = append(spec.Steps, step) + + // if the repository is mounted from a local + // volume we should disable cloning. + if c.Mount != "" { + step.RunPolicy = engine.RunNever + } } // create steps diff --git a/scripts/windows/latest.ps1 b/scripts/windows/latest.ps1 new file mode 100644 index 0000000..5da65ef --- /dev/null +++ b/scripts/windows/latest.ps1 @@ -0,0 +1,18 @@ +# this script is used by the continuous integration server to +# build and publish the docker image for a commit to master. + +$env:GOOS=windows +$env:GOARCH=amd64 +$env:CGO_ENABLED=0 +$env:VERSION=1809 + +# build the binary +go build -o release/windows/amd64/drone-runner-docker.exe + +# build and publish the docker image +docker login -u $env:USERNAME -p $env:PASSWORD +docker build -f docker/Dockerfile.windows.$env:VERSION -t drone/drone-runner-docker:windows-$env:VERSION-amd64 . +docker push drone/drone-runner-docker:windows-$env:VERSION-amd64 + +# remove images from local cache +docker rmi drone/drone-runner-docker:windows-$env:VERSION-amd64 diff --git a/scripts/windows/tag.ps1 b/scripts/windows/tag.ps1 new file mode 100644 index 0000000..a4d721c --- /dev/null +++ b/scripts/windows/tag.ps1 @@ -0,0 +1,33 @@ +# this script is used by the continuous integration server to +# build and publish the docker image for a tagged revsision. + +$env:GOOS=windows +$env:GOARCH=amd64 +$env:CGO_ENABLED=0 +$env:VERSION=1903 + +# define the image tags +$env:IMAGE_PATCH=drone/drone-runner-docker:$env:DRONE_SEMVER_SHORT-windows-$env:VERSION-amd64 +$env:IMAGE_MAJOR=drone/drone-runner-docker:$env:DRONE_SEMVER_MAJOR-windows-$env:VERSION-amd64 +$env:IMAGE_MINOR=drone/drone-runner-docker:$env:DRONE_SEMVER_MAJOR.$env:DRONE_SEMVER_MINOR-windows-$env:VERSION-amd64 + +# build the binary +go build -o release/windows/amd64/drone-runner-docker.exe + +# authenticate with the docker registry +docker login -u $env:USERNAME -p $env:PASSWORD + +# build and tag the docker images +docker build -f docker/Dockerfile.windows.$env:VERSION -t $env:IMAGE_PATCH . +docker tag $env:IMAGE_PATCH $env:IMAGE_MAJOR +docker tag $env:IMAGE_PATCH $env:IMAGE_MINOR + +# publish the docker images +docker push $env:IMAGE_MAJOR +docker push $env:IMAGE_MINOR +docker push $env:IMAGE_PATCH + +# remove images after from local cache +docker rmi $env:IMAGE_MAJOR +docker rmi $env:IMAGE_MINOR +docker rmi $env:IMAGE_PATCH