diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e9db1bc2..221c3653 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,25 +12,50 @@ on: jobs: build: runs-on: ubuntu-20.04 + env: + CACHE_REGISTRY: ghcr.io steps: - name: Checkout uses: actions/checkout@v2 - - name: Install dependencies + - name: Define custom env variables + run: | + echo "CACHE_REGISTRY_PREFIX=${CACHE_REGISTRY}/asciidoctor" >> $GITHUB_ENV + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + - name: Login to Docker Hub + uses: docker/login-action@v1 + with: + registry: ${{ env.CACHE_REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Build + run: | + make build + - name: Deploy Cache + # Only upstream has the cache registry credential as PRs cannot be trusted + if: github.event_name != 'pull_request' + run: | + make cache + - name: Install dependencies for Tests run: | sudo apt-get update sudo apt-get install -y --no-install-recommends bats - - name: Set up Git user + - name: Test + run: make test + - name: Set up Git user for deploy and custom README run: | git config --local user.name "${GITHUB_ACTOR}" git config --local user.email "${GITHUB_ACTOR}@users.noreply.github.com" - - name: Build + - name: Generate README + run: make README + - name: Define custom env variables for deployment + if: github.event_name != 'pull_request' run: | - make build - make test - make README + echo "DEPLOY_IMAGE_NAME=${GITHUB_ACTOR}/docker-asciidoctor:$(echo ${GITHUB_REF#refs/*/})" >> $GITHUB_ENV - name: Deploy if: github.event_name != 'pull_request' - run: make deploy-README deploy env: DOCKERHUB_SOURCE_TOKEN: ${{ secrets.DOCKERHUB_SOURCE_TOKEN }} DOCKERHUB_TRIGGER_TOKEN: ${{ secrets.DOCKERHUB_TRIGGER_TOKEN }} + DOCKERHUB_FINAL_IMAGE_NAME: "${GITHUB_ACTOR}" + run: make deploy-README deploy diff --git a/Makefile b/Makefile index 5af422b5..cebf8599 100644 --- a/Makefile +++ b/Makefile @@ -1,69 +1,32 @@ -DOCKER_IMAGE_NAME ?= docker-asciidoctor -DOCKERHUB_USERNAME ?= asciidoctor export DOCKER_BUILDKIT=1 -GIT_TAG = $(shell git describe --exact-match --tags HEAD 2>/dev/null) -ifeq ($(strip $(GIT_TAG)),) -GIT_REF = $(shell git rev-parse --abbrev-ref HEAD 2>/dev/null) -else -GIT_REF = $(GIT_TAG) -endif -DOCKER_IMAGE_TAG ?= $(shell echo $(GIT_REF) | sed 's/\//-/' ) -DOCKER_IMAGE_NAME_TO_TEST ?= $(DOCKERHUB_USERNAME)/$(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_TAG) -export DOCKER_IMAGE_NAME_TO_TEST - -TESTS_ENV_FILE ?= $(CURDIR)/tests/env_vars.yml -export TESTS_ENV_FILE PANDOC_VERSION ?= 2.10.1 all: build test README -build: - docker build \ - --target main-minimal \ - --tag="$(DOCKER_IMAGE_NAME_TO_TEST)-minimal" \ - --build-arg BUILDKIT_INLINE_CACHE=1 \ - --cache-from="$(DOCKER_IMAGE_NAME_TO_TEST)-minimal" \ - --file=Dockerfile \ - $(CURDIR)/ - docker build \ - --target build-haskell \ - --tag="$(DOCKER_IMAGE_NAME_TO_TEST)-build-haskell" \ - --build-arg BUILDKIT_INLINE_CACHE=1 \ - --cache-from="$(DOCKER_IMAGE_NAME_TO_TEST)-build-haskell" \ - --file=Dockerfile \ - $(CURDIR)/ - docker build \ - --target main \ - --tag="$(DOCKER_IMAGE_NAME_TO_TEST)" \ - --build-arg BUILDKIT_INLINE_CACHE=1 \ - --cache-from="$(DOCKER_IMAGE_NAME_TO_TEST)-minimal" \ - --cache-from="$(DOCKER_IMAGE_NAME_TO_TEST)-build-haskell" \ - --cache-from="$(DOCKER_IMAGE_NAME_TO_TEST)" \ - --file=Dockerfile \ - $(CURDIR)/ +build: asciidoctor-minimal.build build-haskell.build asciidoctor.build + +%.build: + docker buildx bake $(*) --load + +cache: asciidoctor-minimal.cache build-haskell.cache asciidoctor.cache + +%.cache: + docker buildx bake $(*) --push shell: build - docker run -it -v $(CURDIR)/tests/fixtures:/documents/ $(DOCKER_IMAGE_NAME_TO_TEST) - -test: - bats $(CURDIR)/tests/*.bats - -deploy: -ifdef DOCKERHUB_SOURCE_TOKEN -ifdef DOCKERHUB_TRIGGER_TOKEN - curl --verbose --header "Content-Type: application/json" \ - --data '{"source_type": "$(shell [ -n "$(GIT_TAG)" ] && echo Tag || echo Branch)", "source_name": "$(GIT_REF)"}' \ - -X POST https://hub.docker.com/api/build/v1/source/$(DOCKERHUB_SOURCE_TOKEN)/trigger/$(DOCKERHUB_TRIGGER_TOKEN)/call/ -else - @echo 'Unable to deploy: Please define $$DOCKERHUB_TRIGGER_TOKEN' - @exit 1 -endif -else - @echo 'Unable to deploy: Please define $$DOCKERHUB_SOURCE_TOKEN' - @exit 1 -endif + docker run -it -v $(CURDIR)/tests/fixtures:/documents/ $(DOCKER_IMAGE) + +test: asciidoctor.test + +%.test: + bats $(CURDIR)/tests/$(*).bats + +deploy: asciidoctor.deploy + +%.deploy: + docker push $(*) clean: rm -rf "$(CURDIR)/cache" @@ -80,14 +43,14 @@ cache/pandoc-$(PANDOC_VERSION)/bin/pandoc: cache/pandoc-$(PANDOC_VERSION)-linux. # GitHub renders asciidoctor but DockerHub requires markdown. # This recipe creates README.md and README.adoc from README-original.adoc and env_vars.yml. -README: build cache/pandoc-$(PANDOC_VERSION)/bin/pandoc +README: asciidoctor.build cache/pandoc-$(PANDOC_VERSION)/bin/pandoc cat tests/env_vars.yml | sed -e 's/^[A-Z]/:&/' | sed '/^#/d' > "$(CURDIR)/cache/env_vars.adoc" cat "$(CURDIR)/cache/env_vars.adoc" README-original.adoc > README.adoc - docker run --rm -t -v $(CURDIR):/documents --entrypoint bash $(DOCKER_IMAGE_NAME_TO_TEST) \ + docker run --rm -t -v $(CURDIR):/documents --entrypoint bash asciidoctor \ -c "asciidoctor -b docbook -a leveloffset=+1 -o - README.adoc | /documents/cache/pandoc-$(PANDOC_VERSION)/bin/pandoc --atx-headers --wrap=preserve -t gfm -f docbook - > README.md" deploy-README: README git add README.adoc README.md && git commit -s -m "Updating README files using 'make README command'" \ && git push origin $(shell git rev-parse --abbrev-ref HEAD) || echo 'No changes to README files' -.PHONY: all build test shell deploy clean README deploy-README +.PHONY: all build test shell deploy clean README deploy-README cache diff --git a/docker-bake.hcl b/docker-bake.hcl new file mode 100644 index 00000000..283405e9 --- /dev/null +++ b/docker-bake.hcl @@ -0,0 +1,65 @@ +variable "CACHE_REGISTRY_PREFIX" { + default = "" +} + +variable "DEPLOY_IMAGE_NAME" { + default = "" +} + +group "all" { + targets = [ + "asciidoctor-minimal", + "build-haskell", + "asciidoctor" + ] +} + +target "asciidoctor-minimal" { + dockerfile = "Dockerfile" + context = "." + target = "main-minimal" + tags = [ + "asciidoctor-minimal", + notequal("", CACHE_REGISTRY_PREFIX) ? "${CACHE_REGISTRY_PREFIX}/asciidoctor-minimal:cache" : "asciidoctor-minimal", + notequal("", DEPLOY_IMAGE_NAME) ? "${DEPLOY_IMAGE_NAME}" : "", + ] + args = { + BUILDKIT_INLINE_CACHE = 1 + } + cache-from = [ + notequal("", CACHE_REGISTRY_PREFIX) ? "${CACHE_REGISTRY_PREFIX}/asciidoctor-minimal:cache" : "", + ] +} + +// This image is only used for intermediate steps +target "build-haskell" { + dockerfile = "Dockerfile" + context = "." + target = "build-haskell" + tags = [ + notequal("", CACHE_REGISTRY_PREFIX) ? "${CACHE_REGISTRY_PREFIX}/asciidoctor-build-haskell:cache" : "asciidoctor-build-haskell", + ] + args = { + BUILDKIT_INLINE_CACHE = 1 + } + cache-from = [ + notequal("", CACHE_REGISTRY_PREFIX) ? "${CACHE_REGISTRY_PREFIX}/asciidoctor-build-haskell:cache" : "", + ] +} + +target "asciidoctor" { + dockerfile = "Dockerfile" + context = "." + target = "main" + tags = [ + "asciidoctor", + notequal("", CACHE_REGISTRY_PREFIX) ? "${CACHE_REGISTRY_PREFIX}/asciidoctor:cache" : "asciidoctor", + notequal("", DEPLOY_IMAGE_NAME) ? "${DEPLOY_IMAGE_NAME}" : "", + ] + args = { + BUILDKIT_INLINE_CACHE = 1 + } + cache-from = [ + notequal("", CACHE_REGISTRY_PREFIX) ? "${CACHE_REGISTRY_PREFIX}/asciidoctor:cache" : "", + ] +} diff --git a/tests/test_suite.bats b/tests/asciidoctor.bats similarity index 99% rename from tests/test_suite.bats rename to tests/asciidoctor.bats index 81e43645..07b5d036 100644 --- a/tests/test_suite.bats +++ b/tests/asciidoctor.bats @@ -1,7 +1,8 @@ #!/usr/bin/env bats TMP_GENERATION_DIR="${BATS_TEST_DIRNAME}/tmp" -export TMP_GENERATION_DIR +TESTS_ENV_FILE="${BATS_TEST_DIRNAME}/env_vars.yml" +DOCKER_IMAGE_NAME_TO_TEST="asciidoctor" ## Load environment variables from file if [ -n "${TESTS_ENV_FILE}" ] && [ -f "${TESTS_ENV_FILE}" ]