From 34f27285bf609330af00c47d7b4807a43bcfefdb Mon Sep 17 00:00:00 2001 From: Robert Kaussow Date: Mon, 30 Oct 2023 11:40:39 +0100 Subject: [PATCH] refactor: rework ci config and use buildx for container builds --- .dockerignore | 2 - .drone.star | 358 ------------------ .drone.yml | 191 ++++++++++ .gitignore | 1 - .../Dockerfile.amd64 => Dockerfile.multiarch | 15 +- Makefile | 5 +- README.md | 50 +-- docker/Dockerfile.arm64 | 22 -- docker/manifest.tmpl | 17 - 9 files changed, 231 insertions(+), 430 deletions(-) delete mode 100644 .dockerignore delete mode 100644 .drone.star create mode 100644 .drone.yml rename docker/Dockerfile.amd64 => Dockerfile.multiarch (81%) delete mode 100644 docker/Dockerfile.arm64 delete mode 100644 docker/manifest.tmpl diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index 92d6c40..0000000 --- a/.dockerignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!dist/ diff --git a/.drone.star b/.drone.star deleted file mode 100644 index d3d3cc1..0000000 --- a/.drone.star +++ /dev/null @@ -1,358 +0,0 @@ -def main(ctx): - before = test(ctx) - - stages = [ - docker(ctx, "amd64"), - docker(ctx, "arm64"), - build(ctx), - ] - - after = manifest(ctx) + pushrm(ctx) - - for b in before: - for s in stages: - s["depends_on"].append(b["name"]) - - for s in stages: - for a in after: - a["depends_on"].append(s["name"]) - - return before + stages + after - -def test(ctx): - return [{ - "kind": "pipeline", - "type": "docker", - "name": "test", - "platform": { - "os": "linux", - "arch": "amd64", - }, - "steps": [ - { - "name": "deps", - "image": "docker.io/golang:1.21", - "commands": [ - "make deps", - ], - "volumes": [ - { - "name": "godeps", - "path": "/go", - }, - ], - }, - { - "name": "generate", - "image": "docker.io/golang:1.21", - "commands": [ - "make generate", - ], - "volumes": [ - { - "name": "godeps", - "path": "/go", - }, - ], - }, - { - "name": "lint", - "image": "docker.io/golang:1.21", - "commands": [ - "make lint", - ], - "volumes": [ - { - "name": "godeps", - "path": "/go", - }, - ], - }, - { - "name": "test", - "image": "docker.io/golang:1.21", - "commands": [ - "make test", - ], - "volumes": [ - { - "name": "godeps", - "path": "/go", - }, - ], - }, - ], - "volumes": [ - { - "name": "godeps", - "temp": {}, - }, - ], - "trigger": { - "ref": [ - "refs/heads/master", - "refs/tags/**", - "refs/pull/**", - ], - }, - }] - -def build(ctx): - return { - "kind": "pipeline", - "type": "docker", - "name": "build-binaries", - "platform": { - "os": "linux", - "arch": "amd64", - }, - "steps": [ - { - "name": "generate", - "image": "docker.io/golang:1.21", - "pull": "always", - "commands": [ - "make generate", - ], - "volumes": [ - { - "name": "godeps", - "path": "/go", - }, - ], - }, - { - "name": "build", - "image": "docker.io/techknowlogick/xgo:go-1.21.x", - "pull": "always", - "commands": [ - "ln -s /drone/src /source", - "make release", - ], - "volumes": [ - { - "name": "godeps", - "path": "/go", - }, - ], - }, - { - "name": "executable", - "image": "docker.io/golang:1.21", - "pull": "always", - "commands": [ - "$(find dist/ -executable -type f -iname drone-ansible-linux-amd64) --help", - ], - }, - { - "name": "changelog", - "image": "quay.io/thegeeklab/git-chglog", - "commands": [ - "git fetch -tq", - "git-chglog --no-color --no-emoji %s" % (ctx.build.ref.replace("refs/tags/", "") if ctx.build.event == "tag" else "--next-tag unreleased unreleased"), - "git-chglog --no-color --no-emoji -o CHANGELOG.md %s" % (ctx.build.ref.replace("refs/tags/", "") if ctx.build.event == "tag" else "--next-tag unreleased unreleased"), - ], - }, - { - "name": "publish", - "image": "docker.io/plugins/github-release", - "pull": "always", - "settings": { - "api_key": { - "from_secret": "github_token", - }, - "files": [ - "dist/*", - ], - "note": "CHANGELOG.md", - "title": ctx.build.ref.replace("refs/tags/", ""), - "overwrite": True, - }, - "when": { - "ref": [ - "refs/tags/**", - ], - }, - }, - ], - "volumes": [ - { - "name": "godeps", - "temp": {}, - }, - ], - "depends_on": [ - "test", - ], - "trigger": { - "ref": [ - "refs/heads/master", - "refs/tags/**", - "refs/pull/**", - ], - }, - } - -def docker(ctx, arch): - return { - "kind": "pipeline", - "type": "docker", - "name": "build-%s" % (arch), - "platform": { - "os": "linux", - "arch": arch, - }, - "steps": [ - { - "name": "generate", - "image": "docker.io/golang:1.21", - "pull": "always", - "commands": [ - "make generate", - ], - "volumes": [ - { - "name": "godeps", - "path": "/go", - }, - ], - }, - { - "name": "build", - "image": "docker.io/golang:1.21", - "pull": "always", - "commands": [ - "make build", - ], - "volumes": [ - { - "name": "godeps", - "path": "/go", - }, - ], - }, - { - "name": "dryrun", - "image": "docker.io/plugins/docker:20", - "pull": "always", - "settings": { - "dry_run": True, - "dockerfile": "docker/Dockerfile.%s" % (arch), - "repo": "owncloudci/%s" % (ctx.repo.name), - "tags": "latest", - }, - "when": { - "ref": { - "include": [ - "refs/pull/**", - ], - }, - }, - }, - { - "name": "docker", - "image": "docker.io/plugins/docker:20", - "pull": "always", - "settings": { - "username": { - "from_secret": "docker_username", - }, - "password": { - "from_secret": "docker_password", - }, - "auto_tag": True, - "auto_tag_suffix": "%s" % (arch), - "dockerfile": "docker/Dockerfile.%s" % (arch), - "repo": "owncloudci/%s" % (ctx.repo.name), - }, - "when": { - "ref": { - "exclude": [ - "refs/pull/**", - ], - }, - }, - }, - ], - "volumes": [ - { - "name": "godeps", - "temp": {}, - }, - ], - "depends_on": [ - "test", - ], - "trigger": { - "ref": [ - "refs/heads/master", - "refs/tags/**", - "refs/pull/**", - ], - }, - } - -def manifest(ctx): - return [{ - "kind": "pipeline", - "type": "docker", - "name": "manifest", - "steps": [ - { - "name": "manifest", - "image": "docker.io/plugins/manifest", - "settings": { - "auto_tag": "true", - "username": { - "from_secret": "docker_username", - }, - "password": { - "from_secret": "docker_password", - }, - "spec": "docker/manifest.tmpl", - "ignore_missing": "true", - }, - }, - ], - "depends_on": [], - "trigger": { - "ref": [ - "refs/heads/master", - "refs/tags/**", - ], - }, - }] - -def pushrm(ctx): - return [{ - "kind": "pipeline", - "type": "docker", - "name": "pushrm", - "steps": [ - { - "name": "pushrm", - "image": "docker.io/chko/docker-pushrm:1", - "environment": { - "DOCKER_PASS": { - "from_secret": "docker_password", - }, - "DOCKER_USER": { - "from_secret": "docker_username", - }, - "PUSHRM_FILE": "README.md", - "PUSHRM_SHORT": "Drone plugin to provision infrastructure with Ansible", - "PUSHRM_TARGET": "owncloudci/%s" % (ctx.repo.name), - }, - }, - ], - "depends_on": [ - "manifest", - ], - "trigger": { - "ref": [ - "refs/heads/master", - "refs/tags/**", - ], - "status": ["success"], - }, - }] diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..0bbc348 --- /dev/null +++ b/.drone.yml @@ -0,0 +1,191 @@ +--- +kind: pipeline +type: docker +name: test + +platform: + os: linux + arch: amd64 + +steps: + - name: deps + image: docker.io/golang:1.21 + commands: + - make deps + volumes: + - name: godeps + path: /go + + - name: generate + image: docker.io/golang:1.21 + commands: + - make generate + volumes: + - name: godeps + path: /go + + - name: lint + image: docker.io/golang:1.21 + commands: + - make lint + volumes: + - name: godeps + path: /go + + - name: test + image: docker.io/golang:1.21 + commands: + - make test + volumes: + - name: godeps + path: /go + +volumes: + - name: godeps + temp: {} + +trigger: + ref: + - refs/heads/main + - refs/tags/** + - refs/pull/** + +--- +kind: pipeline +type: docker +name: build-binaries + +platform: + os: linux + arch: amd64 + +steps: + - name: build + image: docker.io/techknowlogick/xgo:go-1.21.x + commands: + - ln -s /drone/src /source + - make release + + - name: executable + image: docker.io/golang:1.21 + commands: + - $(find dist/ -executable -type f -iname ${DRONE_REPO_NAME}-linux-amd64) --help + + - name: changelog + image: quay.io/thegeeklab/git-chglog + commands: + - git fetch -tq + - git-chglog --no-color --no-emoji -o CHANGELOG.md ${DRONE_TAG:---next-tag unreleased unreleased} + + - name: publish + image: docker.io/plugins/github-release + settings: + api_key: + from_secret: github_token + files: + - dist/* + note: CHANGELOG.md + overwrite: true + title: refs/heads/main + when: + ref: + - refs/tags/** + +trigger: + ref: + - refs/heads/main + - refs/tags/** + - refs/pull/** + +depends_on: + - test + +--- +kind: pipeline +type: docker +name: build-container + +platform: + os: linux + arch: amd64 + +steps: + - name: dryrun + image: docker.io/owncloudci/drone-docker-buildx:1 + settings: + dockerfile: Dockerfile.multiarch + dry_run: true + platforms: + - linux/amd64 + - linux/arm64 + provenance: false + repo: owncloudci/${DRONE_REPO_NAME} + when: + ref: + - refs/pull/** + + - name: publish + image: docker.io/owncloudci/drone-docker-buildx:1 + settings: + auto_tag: true + dockerfile: Dockerfile.multiarch + password: + from_secret: docker_password + platforms: + - linux/amd64 + - linux/arm64 + provenance: false + repo: owncloudci/${DRONE_REPO_NAME} + username: + from_secret: docker_username + when: + ref: + - refs/heads/main + - refs/tags/** + depends_on: + - dryrun + +trigger: + ref: + - refs/heads/main + - refs/tags/** + - refs/pull/** + +depends_on: + - test + +--- +kind: pipeline +type: docker +name: notifications + +platform: + os: linux + arch: amd64 + +steps: + - name: pushrm + image: docker.io/chko/docker-pushrm:1 + environment: + DOCKER_PASS: + from_secret: docker_password + DOCKER_USER: + from_secret: docker_username + PUSHRM_FILE: README.md + PUSHRM_SHORT: Drone plugin to build multiarch Docker images with buildx + PUSHRM_TARGET: owncloudci/${DRONE_REPO_NAME} + when: + status: + - success + +trigger: + ref: + - refs/heads/main + - refs/tags/** + status: + - success + - failure + +depends_on: + - build-binaries + - build-container diff --git a/.gitignore b/.gitignore index b01182f..1f61343 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,4 @@ /drone-ansible* coverage.out -.drone.yml CHANGELOG.md diff --git a/docker/Dockerfile.amd64 b/Dockerfile.multiarch similarity index 81% rename from docker/Dockerfile.amd64 rename to Dockerfile.multiarch index 4dac654..c30bda0 100644 --- a/docker/Dockerfile.amd64 +++ b/Dockerfile.multiarch @@ -1,3 +1,13 @@ +FROM --platform=$BUILDPLATFORM golang:1.21 as build + +ARG TARGETOS +ARG TARGETARCH + +ADD . /src +WORKDIR /src + +RUN make build + FROM docker.io/alpine:3.18@sha256:eece025e432126ce23f223450a0326fbebde39cdf496a85d8c016293fc851978 LABEL maintainer="ownCloud DevOps " @@ -7,6 +17,8 @@ LABEL org.opencontainers.image.url="https://github.com/owncloud-ci/drone-ansible LABEL org.opencontainers.image.source="https://github.com/owncloud-ci/drone-ansible" LABEL org.opencontainers.image.documentation="https://github.com/owncloud-ci/drone-ansible" +ARG TARGETOS +ARG TARGETARCH ARG ANSIBLE_VERSION # renovate: datasource=pypi depName=ansible @@ -17,6 +29,5 @@ RUN apk add --no-cache bash git curl rsync openssh-client sshpass py3-pip py3-re pip3 install ansible=="${ANSIBLE_VERSION}" boto3 hcloud pywinrm passlib jsonschema && \ apk del --no-cache python3-dev libffi-dev build-base -ADD dist/drone-ansible /bin/ - +COPY --from=build /src/dist/drone-docker-buildx /bin/drone-docker-buildx ENTRYPOINT ["/bin/drone-ansible"] diff --git a/Makefile b/Makefile index bdc465b..8cca49e 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ GENERATE ?= $(IMPORT)/pkg/templates XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest GOTESTSUM_PACKAGE ?= gotest.tools/gotestsum@latest XGO_VERSION := go-1.21.x -XGO_TARGETS ?= linux/amd64,linux/arm64,darwin/amd64,darwin/arm64,windows/amd64 +XGO_TARGETS ?= linux/amd64,linux/arm64 TAGS ?= netgo @@ -62,8 +62,7 @@ lint: golangci-lint .PHONY: generate generate: - go generate $(GENERATE) - + $(GO) generate $(GENERATE) .PHONY: test test: diff --git a/README.md b/README.md index 92ca194..971fa3a 100644 --- a/README.md +++ b/README.md @@ -4,35 +4,42 @@ [![Docker Hub](https://img.shields.io/docker/v/owncloudci/drone-ansible?logo=docker&label=dockerhub&sort=semver&logoColor=white)](https://hub.docker.com/r/owncloudci/drone-ansible) [![GitHub contributors](https://img.shields.io/github/contributors/owncloud-ci/drone-ansible)](https://github.com/owncloud-ci/drone-ansible/graphs/contributors) [![Source: GitHub](https://img.shields.io/badge/source-github-blue.svg?logo=github&logoColor=white)](https://github.com/owncloud-ci/drone-ansible) -[![License: Apache-2.0](https://img.shields.io/github/license/owncloud-ci/drone-ansible)](https://github.com/owncloud-ci/drone-ansible/blob/master/LICENSE) +[![License: Apache-2.0](https://img.shields.io/github/license/owncloud-ci/drone-ansible)](https://github.com/owncloud-ci/drone-ansible/blob/main/LICENSE) Drone plugin to provision infrastructure with [Ansible](https://www.ansible.com/). +## Usage + +```yaml +kind: pipeline +type: docker +name: default + +steps: + - name: ansible + image: owncloudci/drone-ansible + settings: + playbook: deployment/playbook.yml + private_key: + from_secret: ansible_private_key + inventory: deployment/hosts.yml +``` + ## Build Build the binary with the following command: ```console -export GOOS=linux -export GOARCH=amd64 -export CGO_ENABLED=0 -export GO111MODULE=on - make build ``` -## Docker - Build the Docker image with the following command: ```console -docker build \ - --label org.label-schema.build-date=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \ - --label org.label-schema.vcs-ref=$(git rev-parse --short HEAD) \ - --file docker/Dockerfile.linux.amd64 --tag plugins/ansible . +docker build --file Dockerfile.multiarch --tag owncloudci/drone-ansible . ``` -## Usage +## Test ```console docker run --rm \ @@ -41,31 +48,24 @@ docker run --rm \ -e PLUGIN_INVENTORY="deployment/hosts.yml" \ -v $(pwd):$(pwd) \ -w $(pwd) \ - plugins/ansible + owncloudci/drone-ansible --dry-run ``` ## Releases -Please create and commit a changelog for the next tag first: - -```Shell -git-chglog -o CHANGELOG.md --next-tag v2.10.3 v2.10.3 -git add CHANGELOG.md; git commit -m "[skip ci] update changelog"; git push -``` +Create and push the new tag to trigger the CI release process: -Afterwards create and push the new tag to trigger the CI release process: - -```Shell +```console git tag v2.10.3 git push origin v2.10.3 ``` ## License -This project is licensed under the Apache 2.0 License - see the [LICENSE](https://github.com/owncloud-ci/drone-ansible/blob/master/LICENSE) file for details. +This project is licensed under the Apache 2.0 License - see the [LICENSE](https://github.com/owncloud-ci/drone-ansible/blob/main/LICENSE) file for details. ## Copyright -```Text +```text Copyright (c) 2022 ownCloud GmbH ``` diff --git a/docker/Dockerfile.arm64 b/docker/Dockerfile.arm64 deleted file mode 100644 index 97f6977..0000000 --- a/docker/Dockerfile.arm64 +++ /dev/null @@ -1,22 +0,0 @@ -FROM docker.io/arm64v8/alpine:3.18@sha256:6ce9a9a256a3495ae60ab0059ed1c7aee5ee89450477f2223f6ea7f6296df555 - -LABEL maintainer="ownCloud DevOps " -LABEL org.opencontainers.image.authors="ownCloud DevOps " -LABEL org.opencontainers.image.title="drone-ansible" -LABEL org.opencontainers.image.url="https://github.com/owncloud-ci/drone-ansible" -LABEL org.opencontainers.image.source="https://github.com/owncloud-ci/drone-ansible" -LABEL org.opencontainers.image.documentation="https://github.com/owncloud-ci/drone-ansible" - -ARG ANSIBLE_VERSION - -# renovate: datasource=pypi depName=ansible -ENV ANSIBLE_VERSION="${ANSIBLE_VERSION:-8.5.0}" - -RUN apk add --no-cache bash git curl rsync openssh-client sshpass py3-pip py3-requests py3-paramiko python3-dev libffi-dev build-base && \ - pip3 install -U pip && \ - pip3 install ansible=="${ANSIBLE_VERSION}" boto3 hcloud pywinrm passlib jsonschema && \ - apk del --no-cache python3-dev libffi-dev build-base - -ADD dist/drone-ansible /bin/ - -ENTRYPOINT ["/bin/drone-ansible"] diff --git a/docker/manifest.tmpl b/docker/manifest.tmpl deleted file mode 100644 index d0c48a3..0000000 --- a/docker/manifest.tmpl +++ /dev/null @@ -1,17 +0,0 @@ -image: owncloudci/drone-ansible:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}latest{{/if}} -{{#if build.tags}} -tags: -{{#each build.tags}} - - {{this}} -{{/each}} -{{/if}} -manifests: - - image: owncloudci/drone-ansible:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}amd64 - platform: - architecture: amd64 - os: linux - - image: owncloudci/drone-ansible:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}arm64 - platform: - architecture: arm64 - os: linux - variant: v8