Created
January 9, 2021 18:28
-
-
Save djm/167dd9db0dbdf9316254306c90dbc1aa to your computer and use it in GitHub Desktop.
Problem: pulling docker images with dynamically generated tags, using just the GitHub Action yaml syntax
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build Docker image & run dependent jobs that pull tagged image | |
| # Desires: | |
| # | |
| # 1) First job builds, pushes and tags docker image with ref/pr-number/sha - something specific to that branch. | |
| # 2) n-jobs after this depend on success of first job, and will pull an image based on tag used in first job. | |
| # 3) The n-jobs mount host GA workspace, or checkout code within the container itself. Not bothered which. | |
| # 4) Rely on GitHub Action's yaml docker constructs only, rather than calling docker @ the cli | |
| # This is not a _true_ requirement! I know how to get around it, but it is what I originally | |
| # set out hoping to do - because it works very nicely when you're dealing with static tags | |
| # (e.g 'latest'). Though, if we were to use only static tags with this per-branch flow you would | |
| # create a race condition when multiple open PRs result in image rebuilds (`latest` tag may not | |
| # be the one from your branch). | |
| on: | |
| push: | |
| branches: | |
| - master | |
| pull_request: | |
| types: [opened, synchronize, reopened] | |
| jobs: | |
| # This job runs successfully (at least when dependent_job_b is not defined) | |
| docker-build-push: | |
| name: Build Docker image & push | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v1 | |
| # Docker Meta handles manipulating various | |
| # GitHub Action contexts into sane Docker | |
| # image tags, based on whether this is a | |
| # push to a mainline branch or a pull request. | |
| # | |
| # dev/master -> :dev/:master & sha | |
| # pr -> :pr2 & sha | |
| # | |
| - name: Instantiate Docker Meta | |
| id: docker_meta | |
| uses: crazy-max/ghaction-docker-meta@v1 | |
| with: | |
| images: example-org/example-repo | |
| tag-sha: true | |
| # Sets up buildx to work with GitHub Actions | |
| # Cache. This caches buildx's layers, so that | |
| # rebuilding reuses layers that have not changed. | |
| - name: Cache Docker layers | |
| uses: actions/cache@v2 | |
| with: | |
| path: /tmp/.buildx-cache | |
| key: ${{ runner.os }}-buildx-${{ github.sha }} | |
| # This restore key means "fall back to the latest | |
| # key that is prefixed like this"; this means that | |
| # a cache miss on the exact key will fallback to the | |
| # most recently created buildx cache key. This is | |
| # safe because it's a layer cache, and buildx will | |
| # only pull a cached layer if it knows it needs it | |
| # (they are content addressed). | |
| restore-keys: | | |
| ${{ runner.os }}-buildx- | |
| - name: Login to DockerHub | |
| uses: docker/login-action@v1 | |
| with: | |
| username: ${{ secrets.DOCKER_HUB_USERNAME }} | |
| password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} | |
| - name: Build and push | |
| uses: docker/build-push-action@v2 | |
| with: | |
| # Pull forces Docker to check the network for the | |
| # latest version of base images. With this enabled | |
| # we can trust that we're always using the latest | |
| # base image, as it will fail when it cannot verify | |
| # that rather than building with the local latest. | |
| pull: true | |
| # Ensures the image is pushed to the DH repo on build. | |
| push: true | |
| # Use Docker Meta output to set correct tags & labels. | |
| tags: ${{ steps.docker_meta.outputs.tags }} | |
| labels: ${{ steps.docker_meta.outputs.labels }} | |
| # Ensure we read & write to the GH action cache. | |
| cache-from: type=local,src=/tmp/.buildx-cache | |
| cache-to: type=local,dest=/tmp/.buildx-cache | |
| # This dependent job uses job.container.image. The workflow runs, but fails | |
| # immediately on this job with: "invalid reference format" on the "Initialize containers" step. | |
| dependent_job_example_a: | |
| name: Check thing a | |
| needs: docker-build-push | |
| runs-on: ubuntu-latest | |
| container: | |
| image: example-org/example-repo:${{ github.sha }} # <-- the cause. | |
| steps: | |
| - name: Check out the repository inside the container | |
| uses: actions/checkout@v2 | |
| - name: Run thing a inside the container | |
| run: echo "thing a" | |
| # This dependent job uses job.steps[x].uses, and fails the entire | |
| # workflow immediately with: | |
| # | |
| # "The workflow is not valid. .github/workflows/workflow.yml (Line: x, Col: x): Unrecognized named-value: 'github'." | |
| # | |
| dependent_job_example_b: | |
| name: Check thing b | |
| needs: docker-build-push | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check out the repository on the guest | |
| uses: actions/checkout@v2 | |
| - name: Run thing b inside the container, having mounted workspace. | |
| uses: docker://example-org/example-repo:${{ github.sha }} # <-- cause | |
| with: | |
| entrypoint: /bin/echo | |
| args: "Hello" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
For anyone looking for a solution, you can use
workflow_callusingoutputsandinputs.outputwhen calling the next jobworflow_callinputsin container image