Skip to content

Commit

Permalink
Implement reuse of base images across jobs
Browse files Browse the repository at this point in the history
  • Loading branch information
ianpittwood committed Apr 11, 2024
1 parent f35d4bc commit 9156678
Show file tree
Hide file tree
Showing 6 changed files with 249 additions and 7 deletions.
6 changes: 0 additions & 6 deletions .github/actions/bake-test-push/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,6 @@ runs:
id: build
uses: docker/bake-action@v4
with:
set: |
*.cache-from=type=gha
*.cache-to=type=gha,compression=zstd
targets: "${{ inputs.target }}"
push: false

Expand All @@ -111,8 +108,5 @@ runs:
- name: Push - ${{ inputs.push-image }}
uses: docker/bake-action@v4
with:
set: |
*.cache-from=type=gha
*.cache-to=type=gha,compression=zstd
targets: "${{ inputs.target }}"
push: ${{ inputs.push-image }}
134 changes: 133 additions & 1 deletion .github/workflows/build-bake.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ jobs:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Just
uses: extractions/setup-just@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
id: setup-buildx
Expand All @@ -41,6 +50,16 @@ jobs:
dockerhub-token: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
gcp-json: '${{ secrets.GCP_ARTIFACT_REGISTRY_JSON }}'

- name: Export artifacts
run: |
just export-artifacts base-images
- name: Upload artifacts
uses: actions/upload-artifact@v2
with:
name: base-images
path: ./.out

connect:
needs: [base]
name: Connect
Expand All @@ -63,6 +82,25 @@ jobs:
with:
buildkitd-config: ./share/buildkitd.toml

- name: Set up Just
uses: extractions/setup-just@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Download artifacts
uses: actions/download-artifact@v2
with:
name: base-images
path: ./.out

- name: Import artifacts
run: |
just import-artifacts
- name: Build, Test, and Push
uses: ./.github/actions/bake-test-push
with:
Expand Down Expand Up @@ -96,6 +134,25 @@ jobs:
with:
buildkitd-config: ./share/buildkitd.toml

- name: Set up Just
uses: extractions/setup-just@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Download artifacts
uses: actions/download-artifact@v2
with:
name: base-images
path: ./.out

- name: Import artifacts
run: |
just import-artifacts
- name: Build, Test, and Push
uses: ./.github/actions/bake-test-push
with:
Expand Down Expand Up @@ -161,6 +218,25 @@ jobs:
with:
buildkitd-config: ./share/buildkitd.toml

- name: Set up Just
uses: extractions/setup-just@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Download artifacts
uses: actions/download-artifact@v2
with:
name: base-images
path: ./.out

- name: Import artifacts
run: |
just import-artifacts
- name: Build, Test, and Push
uses: ./.github/actions/bake-test-push
with:
Expand Down Expand Up @@ -194,6 +270,25 @@ jobs:
with:
buildkitd-config: ./share/buildkitd.toml

- name: Set up Just
uses: extractions/setup-just@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Download artifacts
uses: actions/download-artifact@v2
with:
name: base-images
path: ./.out

- name: Import artifacts
run: |
just import-artifacts
- name: Build, Test, and Push
uses: ./.github/actions/bake-test-push
with:
Expand Down Expand Up @@ -227,6 +322,25 @@ jobs:
with:
buildkitd-config: ./share/buildkitd.toml

- name: Set up Just
uses: extractions/setup-just@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Download artifacts
uses: actions/download-artifact@v2
with:
name: base-images
path: ./.out

- name: Import artifacts
run: |
just import-artifacts
- name: Build, Test, and Push
uses: ./.github/actions/bake-test-push
with:
Expand All @@ -239,7 +353,6 @@ jobs:
gcp-json: '${{ secrets.GCP_ARTIFACT_REGISTRY_JSON }}'

workbench-for-google-cloud-workstations:
needs: [base]
name: Workbench for Google Cloud Workstations
runs-on: ubuntu-latest-4x

Expand Down Expand Up @@ -293,6 +406,25 @@ jobs:
with:
buildkitd-config: ./share/buildkitd.toml

- name: Set up Just
uses: extractions/setup-just@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Download artifacts
uses: actions/download-artifact@v2
with:
name: base-images
path: ./.out

- name: Import artifacts
run: |
just import-artifacts
- name: Build, Test, and Push
uses: ./.github/actions/bake-test-push
with:
Expand Down
8 changes: 8 additions & 0 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,14 @@ run product tag="":
-e RSPM_VERSION="${RSPM_VERSION}" \
{{product}}

# Export/import targets

export-artifacts target build_definition="docker-bake.hcl":
python3 {{justfile_directory()}}/tools/export_bake_artifacts.py --target "{{target}}" --file "{{build_definition}}"

import-artifacts:
python3 {{justfile_directory()}}/tools/import_bake_artifacts.py

# Helper targets

# just _get-tag-safe-version 2022.07.2+576.pro12
Expand Down
67 changes: 67 additions & 0 deletions tools/export_bake_artifacts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#!/usr/bin/env python3
"""
Export bake artifacts as tar files for later reuse.
./export_bake_artifacts.py --file <build definition> --target <build target or group> --output-path <output path>
"""

import argparse
import json
import subprocess
from pathlib import Path

PROJECT_DIR = Path(__file__).resolve().parents[1]


parser = argparse.ArgumentParser(
description="Export one or more bake artifacts to tar files for reuse"
)
parser.add_argument("--file", default="docker-bake.hcl")
parser.add_argument("--target", default="default")
parser.add_argument("--output-path", default=PROJECT_DIR / ".out")


def get_bake_plan(bake_file="docker-bake.hcl", target="default"):
cmd = ["docker", "buildx", "bake", "-f", str(PROJECT_DIR / bake_file), "--print", target]
p = subprocess.run(cmd, capture_output=True)
if p.returncode != 0:
print(f"Failed to get bake plan: {p.stderr}")
exit(1)
return json.loads(p.stdout.decode("utf-8"))


def build_export_command(target_name, target_spec, output_path):
output_file = Path(output_path) / f"{target_name}.tar"
cmd = [
"docker",
"image",
"save",
"--output",
f"{output_file}",
" ".join(target_spec["tags"]),
]
return cmd


def run_cmd(target_name, cmd):
p = subprocess.run(" ".join(cmd), shell=True)
if p.returncode != 0:
print(f"{target_name} failed to export: {p.returncode}")
return p.returncode


def main():
args = parser.parse_args()
plan = get_bake_plan(args.file, args.target)
output = args.output_path
if not Path(output).exists():
Path(output).mkdir(parents=True)
print(f"Exporting {len(plan['target'].keys())} targets: {plan['target'].keys()}")
for target_name, target_spec in plan["target"].items():
print(f"Exporting {target_name}")
cmd = build_export_command(target_name, target_spec, output)
run_cmd(target_name, cmd)


if __name__ == "__main__":
main()
34 changes: 34 additions & 0 deletions tools/import_bake_artifacts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/usr/bin/env python3
"""
Run tests against bake artifacts by group/target and build definition.
./test_bake_artifacts.py --file <build definition> --target <build target or group>
"""

import argparse
import json
import subprocess
from pathlib import Path

PROJECT_DIR = Path(__file__).resolve().parents[1]


parser = argparse.ArgumentParser(
description="Import one or more bake artifacts from tar files for reuse"
)
parser.add_argument("--archive-path", type=Path, default=PROJECT_DIR / ".out")


def main():
args = parser.parse_args()
if args.archive_path:
for archive in args.archive_path.glob("*.tar"):
print(f"Importing {archive}")
cmd = ["docker", "image", "load", "--input", archive]
p = subprocess.run(cmd)
if p.returncode != 0:
print(f"Failed to import {archive}: {p.returncode}")


if __name__ == "__main__":
main()
7 changes: 7 additions & 0 deletions tools/test_bake_artifacts.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
#!/usr/bin/env python3
"""
Run tests against bake artifacts by group/target and build definition.
./test_bake_artifacts.py --file <build definition> --target <build target or group>
"""

import argparse
import json
import re
Expand Down

0 comments on commit 9156678

Please sign in to comment.