aboutsummaryrefslogtreecommitdiffstats
path: root/.github/workflows/build.yaml
blob: 1be5d2fc00981d05c4aa04a0a9f7caa17dcc1dba (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
on:
  workflow_call:
    outputs:
      artifact:
        description: The name of the uploaded image aretfact.
        value: ${{ jobs.build.outputs.artifact }}
      version:
        description: The package's version.
        value: ${{ jobs.build.outputs.version }}

jobs:
  build:
    name: Build snekbox-venv image
    runs-on: ubuntu-latest
    outputs:
      artifact: ${{ env.artifact }}
      version: ${{ steps.version.outputs.version }}
    env:
      artifact: image_artifact_snekbox-venv

    steps:
      - name: Checkout code
        uses: actions/checkout@v2
        with:
          # The version script relies on history. Fetch 100 commits to be safe.
          fetch-depth: 100

      - name: Get version
        id: version
        run: |
          set -eu
          version=$(python scripts/version.py)
          echo "::set-output name=version::$version"
          printf "%s\n" "${version}"

      # The current version (v2) of Docker's build-push action uses buildx,
      # which comes with BuildKit. It has cache features which can speed up
      # the builds. See https://github.com/docker/build-push-action
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1

      - name: Log in to GitHub Container Registry
        uses: docker/login-action@v1
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN  }}

      # The image built for PRs may start to deviate from the "latest" image
      # currently in GHCR. Configure the subsequent build step to cache the
      # layers in GitHub Actions for PRs.
      # See https://github.com/moby/buildkit#github-actions-cache-experimental
      #
      # Because the cache is scoped to the branch, it will not be available
      # on the main branch when the PR is merged. Furthermore, using this cache
      # on main is redundant since the previous build's images are already
      # cached on GHCR. Thus, this step is only used for PRs.
      - name: Configure cache
        id: cache_config
        run: |
          set -eu
          if [ "$GITHUB_EVENT_NAME" = 'pull_request' ]; then
            cache_from="type=gha,scope=buildkit-${GITHUB_REF}"
            cache_to="${cache_from},mode=max"
          fi
          echo "::set-output name=cache_from::${cache_from:-}"
          echo "::set-output name=cache_to::${cache_to:-}"

      # Build the "DEV" version of the image, which targets the `venv` stage
      # and includes development dependencies.
      #
      # Include an inline cache manifest in the image to support caching from
      # GHCR. This enables subsequent builds to pull reusable layers from GHCR.
      # If configured by the cache_config step, also cache the layers in
      # GitHub Actions.
      - name: Build image for linting and testing
        uses: docker/build-push-action@v2
        with:
          context: .
          file: ./Dockerfile
          push: false
          target: venv
          build-args: DEV=1
          outputs: type=docker,dest=${{ env.artifact }}.tar
          cache-from: |
            ${{ steps.cache_config.outputs.cache_from }}
            ghcr.io/python-discord/snekbox-base:latest
            ghcr.io/python-discord/snekbox-venv:latest
          cache-to: ${{ steps.cache_config.outputs.cache_to }}
          tags: ghcr.io/python-discord/snekbox-venv:${{ steps.version.outputs.version }}

      # Make the image available as an artifact so other jobs will be able to
      # download it.
      - name: Upload image archive as an artifact
        uses: actions/upload-artifact@v2
        with:
          name: ${{ env.artifact }}
          path: ${{ env.artifact }}.tar
          retention-days: 1  # It's only needed for the duration of the workflow.
          if-no-files-found: error