From 5aaac7225051fabd97ad7f7e9ea6472b8d2d7a8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Molinero=20Fern=C3=A1ndez?= Date: Tue, 26 Apr 2022 22:11:31 +0200 Subject: [PATCH] Migration to GitHub Actions and image namespace update --- .github/dependabot.yml | 8 ++ .github/workflows/ci.yml | 25 ---- .github/workflows/main.yml | 110 ++++++++++++++++++ .github/workflows/rebuild-latest-release.yml | 33 ++++++ .../trigger-rebuild-latest-release.yml | 26 ----- .gitlab-ci.yml | 74 ------------ Dockerfile.m4 | 2 +- Makefile | 17 +-- README.md | 2 +- run.sh | 2 +- 10 files changed, 164 insertions(+), 135 deletions(-) create mode 100644 .github/dependabot.yml delete mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/main.yml create mode 100644 .github/workflows/rebuild-latest-release.yml delete mode 100644 .github/workflows/trigger-rebuild-latest-release.yml delete mode 100644 .gitlab-ci.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..e449e73 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,8 @@ +version: 2 + +updates: + + - package-ecosystem: 'github-actions' + directory: '/' + schedule: + interval: 'daily' diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index 76ed0d5..0000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: 'CI' - -on: - push: - tags: ['*'] - branches: ['*'] - pull_request: - branches: ['*'] - workflow_dispatch: - -jobs: - - build: - name: 'Build ${{ matrix.arch }} image' - runs-on: 'ubuntu-latest' - strategy: - matrix: - arch: ['amd64', 'arm64v8', 'arm32v7'] - steps: - - name: 'Checkout project' - uses: 'actions/checkout@v3' - - name: 'Build image' - run: | - make binfmt-register - make IMAGE_BUILD_OPTS="--pull" "build-${{ matrix.arch }}-image" diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..e434d40 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,110 @@ +name: 'Main' + +on: + push: + tags: ['*'] + branches: ['*'] + pull_request: + branches: ['*'] + workflow_dispatch: + +jobs: + + build: + name: 'Build ${{ matrix.arch }} image' + runs-on: 'ubuntu-latest' + permissions: + contents: 'read' + strategy: + matrix: + arch: ['native', 'amd64', 'arm64v8', 'arm32v7'] + steps: + - name: 'Checkout project' + uses: 'actions/checkout@v3' + - name: 'Register binfmt entries' + if: "matrix.arch != 'native'" + run: | + make binfmt-register + - name: 'Build and save image' + run: | + make IMAGE_BUILD_OPTS="--pull" "build-${{ matrix.arch }}-image" "save-${{ matrix.arch }}-image" + - name: 'Upload artifacts' + if: "startsWith(github.ref, 'refs/tags/v')" + uses: 'actions/upload-artifact@v3' + with: + name: 'dist-${{ matrix.arch }}' + path: './dist/' + retention-days: 1 + + push: + name: 'Push ${{ matrix.arch }} image' + if: "startsWith(github.ref, 'refs/tags/v')" + needs: ['build'] + runs-on: 'ubuntu-latest' + permissions: + contents: 'read' + strategy: + matrix: + arch: ['amd64', 'arm64v8', 'arm32v7'] + steps: + - name: 'Checkout project' + uses: 'actions/checkout@v3' + - name: 'Download artifacts' + uses: 'actions/download-artifact@v3' + with: + name: 'dist-${{ matrix.arch }}' + path: './dist/' + - name: 'Login to Docker Hub' + uses: 'docker/login-action@v1' + with: + registry: 'docker.io' + username: '${{ secrets.DOCKERHUB_USERNAME }}' + password: '${{ secrets.DOCKERHUB_TOKEN }}' + - name: 'Load and push image' + run: | + make "load-${{ matrix.arch }}-image" "push-${{ matrix.arch }}-image" + + push-manifest: + name: 'Push manifest' + if: "startsWith(github.ref, 'refs/tags/v')" + needs: ['push'] + runs-on: 'ubuntu-latest' + permissions: + contents: 'read' + steps: + - name: 'Checkout project' + uses: 'actions/checkout@v3' + - name: 'Login to Docker Hub' + uses: 'docker/login-action@v1' + with: + registry: 'docker.io' + username: '${{ secrets.DOCKERHUB_USERNAME }}' + password: '${{ secrets.DOCKERHUB_TOKEN }}' + - name: 'Push manifest' + run: | + make push-cross-manifest + + release-github: + name: 'Create GitHub release' + if: "startsWith(github.ref, 'refs/tags/v')" + needs: ['push-manifest'] + runs-on: 'ubuntu-latest' + permissions: + contents: 'write' + steps: + - name: 'Create release' + run: | + RELEASE_STATUS="$(curl -fs --proto '=https' --tlsv1.3 --globoff \ + --url "https://api.github.com/repos/${GITHUB_REPOSITORY:?}/releases/tags/${GITHUB_REF_NAME:?}" \ + --header 'Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' \ + --header 'Accept: application/vnd.github.v3+json' \ + --header 'Content-Type: application/json' \ + --write-out '%{http_code}' --output /dev/null ||:)" + if [ "${RELEASE_STATUS:?}" = '200' ]; then exit 0; fi + RELEASE_ID="$(curl -fsS --proto '=https' --tlsv1.3 --globoff \ + --url "https://api.github.com/repos/${GITHUB_REPOSITORY:?}/releases" \ + --header 'Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' \ + --header 'Accept: application/vnd.github.v3+json' \ + --header 'Content-Type: application/json' \ + --data "$(jq -rn --arg tag "${GITHUB_REF_NAME:?}" '{"name": $tag, "tag_name": $tag, "generate_release_notes": true}')" | jq -r '.id')" + if [ -z "${RELEASE_ID-}" ] || [ "${RELEASE_ID:?}" = 'null' ]; then exit 1; fi diff --git a/.github/workflows/rebuild-latest-release.yml b/.github/workflows/rebuild-latest-release.yml new file mode 100644 index 0000000..8147cac --- /dev/null +++ b/.github/workflows/rebuild-latest-release.yml @@ -0,0 +1,33 @@ +name: 'Rebuild latest release' + +on: + schedule: + - cron: '20 04 * * 1' + workflow_dispatch: + +jobs: + + trigger-rebuild: + name: 'Trigger rebuild' + runs-on: 'ubuntu-latest' + permissions: + contents: 'read' + steps: + - name: 'REST API call' + run: | + RELEASE_TAG="$(curl -fsS --proto '=https' --tlsv1.3 --globoff \ + --url 'https://api.github.com/repos/${{ github.repository }}/releases/latest' \ + --header 'Authorization: Bearer ${{ secrets.PERSONAL_GITHUB_TOKEN }}' \ + --header 'Accept: application/vnd.github.v3+json' \ + --header 'Content-Type: application/json' \ + | jq -rc '.tag_name')" + if [ -n "${RELEASE_TAG-}" ] && [ "${RELEASE_TAG:?}" != 'null' ]; then + curl -fsS --proto '=https' --tlsv1.3 --globoff \ + --url 'https://api.github.com/repos/${{ github.repository }}/actions/workflows/main.yml/dispatches' \ + --header 'Authorization: Bearer ${{ secrets.PERSONAL_GITHUB_TOKEN }}' \ + --header 'Accept: application/vnd.github.v3+json' \ + --header 'Content-Type: application/json' \ + --data "$(jq -rn --arg tag "${RELEASE_TAG:?}" '{"ref": $tag}')" + else + exit 1 + fi diff --git a/.github/workflows/trigger-rebuild-latest-release.yml b/.github/workflows/trigger-rebuild-latest-release.yml deleted file mode 100644 index 7538b26..0000000 --- a/.github/workflows/trigger-rebuild-latest-release.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: 'Trigger rebuild of latest release' - -on: - schedule: - - cron: '20 04 * * 1' - workflow_dispatch: - -jobs: - - trigger-rebuild: - name: 'Trigger rebuild' - runs-on: 'ubuntu-latest' - steps: - - name: 'REST API call' - run: | - curl -fsS --proto '=https' --tlsv1.3 \ - --url 'https://api.github.com/repos/${{ github.repository }}/actions/workflows/ci.yml/dispatches' \ - --header 'Authorization: Bearer ${{ secrets.PERSONAL_GITHUB_TOKEN }}' \ - --header 'Accept: application/vnd.github.v3+json' \ - --header 'Content-Type: application/json' \ - --data "$(curl -fsS --proto '=https' --tlsv1.3 \ - --url 'https://api.github.com/repos/${{ github.repository }}/releases/latest' \ - --header 'Authorization: Bearer ${{ secrets.PERSONAL_GITHUB_TOKEN }}' \ - --header 'Accept: application/vnd.github.v3+json' \ - --header 'Content-Type: application/json' \ - | jq -rc '{ ref: .tag_name }')" diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index 3fa1420..0000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,74 +0,0 @@ -stages: - - 'build' - - 'push' - -variables: - DOCKER_HOST: 'tcp://dockerd:2376' - DOCKER_TLS_SAN: 'DNS:dockerd' - DOCKER_TLS_CERTDIR: '/certs' - DOCKER_DRIVER: 'overlay2' - -default: - image: 'docker.io/docker:latest' - services: - - name: 'docker.io/docker:dind' - alias: 'dockerd' - -.anchors: - - &cmd_install_packages 'apk add --no-cache coreutils git m4 make zstd' - - &cmd_docker_login_registry 'docker login -u "${CI_REGISTRY_USER:?}" -p "${CI_REGISTRY_PASSWORD:?}" "${CI_REGISTRY:?}"' - - &matrix_arch ['amd64', 'arm64v8', 'arm32v7'] - - ®ex_version '/^v[0-9]+$/' - -build:native: - stage: 'build' - except: [*regex_version] - before_script: - - *cmd_install_packages - script: - - 'make IMAGE_BUILD_OPTS="--pull" build-native-image save-native-image' - artifacts: - expire_in: '1 day' - paths: - - './dist/' - -build:cross: - stage: 'build' - only: [*regex_version] - parallel: - matrix: - - ARCH: *matrix_arch - before_script: - - *cmd_install_packages - script: - - 'make binfmt-register' - - 'make IMAGE_BUILD_OPTS="--pull" "build-${ARCH:?}-image" "save-${ARCH:?}-image"' - artifacts: - expire_in: '1 week' - paths: - - './dist/' - -push:cross: - stage: 'push' - needs: ['build:cross'] - only: [*regex_version] - parallel: - matrix: - - ARCH: *matrix_arch - before_script: - - *cmd_install_packages - - *cmd_docker_login_registry - script: - - 'make "load-${ARCH:?}-image" "push-${ARCH:?}-image"' - -push:manifest: - stage: 'push' - needs: ['push:cross'] - only: [*regex_version] - variables: - DOCKER_CLI_EXPERIMENTAL: 'enabled' - before_script: - - *cmd_install_packages - - *cmd_docker_login_registry - script: - - 'make push-cross-manifest' diff --git a/Dockerfile.m4 b/Dockerfile.m4 index 8263eb2..ccdcd8f 100644 --- a/Dockerfile.m4 +++ b/Dockerfile.m4 @@ -93,7 +93,7 @@ RUN mkisofs -no-emul-boot -iso-level 4 -eltorito-boot loader/isoboot.bin -o /tmp ################################################## m4_ifdef([[CROSS_ARCH]], [[FROM docker.io/CROSS_ARCH/ubuntu:20.04]], [[FROM docker.io/ubuntu:20.04]]) AS base -m4_ifdef([[CROSS_QEMU]], [[COPY --from=docker.io/hectormolinero/qemu-user-static:latest CROSS_QEMU CROSS_QEMU]]) +m4_ifdef([[CROSS_QEMU]], [[COPY --from=docker.io/hectorm/qemu-user-static:latest CROSS_QEMU CROSS_QEMU]]) # Install system packages RUN export DEBIAN_FRONTEND=noninteractive \ diff --git a/Makefile b/Makefile index 11e2d2c..1cc0cec 100644 --- a/Makefile +++ b/Makefile @@ -11,10 +11,12 @@ DISTDIR := ./dist DOCKERFILE_TEMPLATE := ./Dockerfile.m4 IMAGE_REGISTRY := docker.io -IMAGE_NAMESPACE := hectormolinero +IMAGE_NAMESPACE := hectorm IMAGE_PROJECT := qemu-reactos IMAGE_NAME := $(IMAGE_REGISTRY)/$(IMAGE_NAMESPACE)/$(IMAGE_PROJECT) -IMAGE_VERSION := $(shell '$(GIT)' describe --abbrev=0 2>/dev/null || printf 'v0') +IMAGE_GIT_TAG := $(shell '$(GIT)' tag -l --contains HEAD 2>/dev/null) +IMAGE_GIT_SHA := $(shell '$(GIT)' rev-parse HEAD 2>/dev/null) +IMAGE_VERSION := $(if $(IMAGE_GIT_TAG),$(IMAGE_GIT_TAG),$(if $(IMAGE_GIT_SHA),$(IMAGE_GIT_SHA),nil)) IMAGE_BUILD_OPTS := @@ -107,7 +109,7 @@ $(IMAGE_ARM32V7_DOCKERFILE): $(DOCKERFILE_TEMPLATE) ################################################## define save_image - '$(DOCKER)' save '$(1)' | zstd -T0 -19 > '$(2)' + '$(DOCKER)' save '$(1)' | zstd -T0 > '$(2)' endef .PHONY: save-native-image @@ -220,7 +222,7 @@ push-cross-manifest: .PHONY: binfmt-register binfmt-register: - '$(DOCKER)' run --rm --privileged docker.io/hectormolinero/qemu-user-static:latest --reset + '$(DOCKER)' run --rm --privileged docker.io/hectorm/qemu-user-static:latest --reset ################################################## ## "version" target @@ -228,12 +230,13 @@ binfmt-register: .PHONY: version version: - @if printf '%s' '$(IMAGE_VERSION)' | grep -q '^v[0-9]\{1,\}$$'; then \ - NEW_IMAGE_VERSION=$$(awk -v 'v=$(IMAGE_VERSION)' 'BEGIN {printf "v%.0f", substr(v,2)+1}'); \ + @LATEST_IMAGE_VERSION=$$('$(GIT)' describe --abbrev=0 2>/dev/null || printf 'v0'); \ + if printf '%s' "$${LATEST_IMAGE_VERSION:?}" | grep -q '^v[0-9]\{1,\}$$'; then \ + NEW_IMAGE_VERSION=$$(awk -v v="$${LATEST_IMAGE_VERSION:?}" 'BEGIN {printf("v%.0f", substr(v,2)+1)}'); \ '$(GIT)' commit --allow-empty -m "$${NEW_IMAGE_VERSION:?}"; \ '$(GIT)' tag -a "$${NEW_IMAGE_VERSION:?}" -m "$${NEW_IMAGE_VERSION:?}"; \ else \ - >&2 printf 'Malformed version string: %s\n' '$(IMAGE_VERSION)'; \ + >&2 printf 'Malformed version string: %s\n' '$${LATEST_IMAGE_VERSION:?}'; \ exit 1; \ fi diff --git a/README.md b/README.md index 2b2f0e4..a67ffaf 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ docker run --detach \ --device /dev/kvm \ --publish 127.0.0.1:5900:5900/tcp \ --publish 127.0.0.1:6080:6080/tcp \ - docker.io/hectormolinero/qemu-reactos:latest + docker.io/hectorm/qemu-reactos:latest ``` The instance can be accessed from: diff --git a/run.sh b/run.sh index 4e34d31..ff2bbc4 100755 --- a/run.sh +++ b/run.sh @@ -6,7 +6,7 @@ export LC_ALL=C DOCKER=$(command -v docker 2>/dev/null) IMAGE_REGISTRY=docker.io -IMAGE_NAMESPACE=hectormolinero +IMAGE_NAMESPACE=hectorm IMAGE_PROJECT=qemu-reactos IMAGE_TAG=latest IMAGE_NAME=${IMAGE_REGISTRY:?}/${IMAGE_NAMESPACE:?}/${IMAGE_PROJECT:?}:${IMAGE_TAG:?}