CI: Deploy to GitHub Container Registry, streamline builds (#7061)

This commit is contained in:
Maximilian Hils 2024-07-29 20:11:41 +02:00 committed by GitHub
parent 5b16adeeff
commit 1a547d2da8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 112 additions and 139 deletions

View File

@ -18,22 +18,22 @@ concurrency:
jobs:
lint:
uses: mhils/workflows/.github/workflows/python-tox.yml@main
uses: mhils/workflows/.github/workflows/python-tox.yml@v7
with:
cmd: tox -e lint
filename-matching:
uses: mhils/workflows/.github/workflows/python-tox.yml@main
uses: mhils/workflows/.github/workflows/python-tox.yml@v7
with:
cmd: tox -e filename_matching
mypy:
uses: mhils/workflows/.github/workflows/python-tox.yml@main
uses: mhils/workflows/.github/workflows/python-tox.yml@v7
with:
cmd: tox -e mypy
individual-coverage:
uses: mhils/workflows/.github/workflows/python-tox.yml@main
uses: mhils/workflows/.github/workflows/python-tox.yml@v7
with:
cmd: tox -e individual_coverage
@ -104,8 +104,6 @@ jobs:
- image: ubuntu-20.04 # Oldest available version so we get oldest glibc possible.
platform: linux
runs-on: ${{ matrix.image }}
env:
CI_BUILD_KEY: ${{ secrets.CI_BUILD_KEY }}
steps:
- uses: actions/checkout@v4
with:
@ -114,11 +112,6 @@ jobs:
- uses: actions/setup-python@v5
with:
python-version-file: .github/python-version.txt
- if: matrix.platform == 'windows'
uses: actions/cache@v4
with:
path: release/installbuilder/setup
key: installbuilder
- run: pip install .[dev] # pyinstaller 5.9 does not like pyproject.toml + editable installs.
- if: startsWith(matrix.platform, 'macos') && github.repository == 'mitmproxy/mitmproxy'
@ -145,16 +138,40 @@ jobs:
# Windows
- if: matrix.platform == 'windows'
run: python -u release/build.py standalone-binaries
- if: matrix.platform == 'windows' && github.repository == 'mitmproxy/mitmproxy' &&
(github.ref == 'refs/heads/citest' || startsWith(github.ref, 'refs/tags/'))
run: python -u release/build.py --dirty installbuilder-installer msix-installer
- uses: actions/upload-artifact@v4
with:
# artifacts must have different names, see https://github.com/actions/upload-artifact/issues/24
name: binaries.${{ matrix.platform }}
path: |
release/dist
path: release/dist
build-wheel:
uses: mhils/workflows/.github/workflows/python-build.yml@v7
with:
python-version-file: .github/python-version.txt
attest-provenance: false # done in deploy step
artifact: binaries.wheel
build-windows-installer:
runs-on: windows-latest
if: github.repository == 'mitmproxy/mitmproxy' && (github.ref == 'refs/heads/citest' || startsWith(github.ref, 'refs/tags/'))
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
fetch-depth: 0
- uses: actions/setup-python@v5
with:
python-version-file: .github/python-version.txt
- run: pip install .[dev] # pyinstaller 5.9 does not like pyproject.toml + editable installs.
- run: python -u release/build.py installbuilder-installer msix-installer
env:
CI_BUILD_KEY: ${{ secrets.CI_BUILD_KEY }}
- uses: actions/upload-artifact@v4
with:
name: binaries.windows-installer
path: release/dist
test-web-ui:
runs-on: ubuntu-latest
@ -183,6 +200,22 @@ jobs:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./web/coverage/coverage-final.json
test-docker:
runs-on: ubuntu-latest
needs: build-wheel
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/download-artifact@v4
with:
name: binaries.wheel
path: release/docker
- name: Build container
run: docker build --tag localtesting release/docker
- name: Test container
run: docker run --rm -v $PWD/release:/release localtesting mitmdump -s /release/selftest.py
docs:
runs-on: ubuntu-latest
steps:
@ -221,41 +254,86 @@ jobs:
- mypy
- individual-coverage
- test
- test-docker
- test-old-dependencies
- test-web-ui
- build
- build-wheel
- build-windows-installer
- docs
uses: mhils/workflows/.github/workflows/alls-green.yml@main
uses: mhils/workflows/.github/workflows/alls-green.yml@v7
with:
jobs: ${{ toJSON(needs) }}
allowed-skips: build-windows-installer
# Separate from everything else because slow.
build-and-deploy-docker:
deploy-docker:
if: github.repository == 'mitmproxy/mitmproxy' && (
github.ref == 'refs/heads/main'
|| github.ref == 'refs/heads/citest'
|| startsWith(github.ref, 'refs/tags/')
)
permissions:
id-token: write
attestations: write
packages: write
environment: deploy-docker
needs: check
runs-on: ubuntu-latest
env:
DOCKER_USERNAME: mitmbot
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/setup-python@v5
with:
python-version-file: .github/python-version.txt
- uses: actions/download-artifact@v4
with:
name: binaries.linux
path: release/dist
name: binaries.wheel
path: release/docker
- uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3.2.0
- uses: docker/setup-buildx-action@3d68780484996aa9d417bb9016193885cdf1f299 # v1.6.0
- run: python release/build-and-deploy-docker.py
- name: Login to Docker Hub
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
with:
username: mitmbot
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GitHub Container Registry
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Docker meta
id: meta
uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81
env:
DOCKER_METADATA_ANNOTATIONS_LEVELS: index
with:
images: |
mitmproxy/mitmproxy
ghcr.io/mitmproxy/mitmproxy
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=raw,value=dev,enable=${{ github.ref == 'refs/heads/main' }}
type=raw,value=citest,enable=${{ github.ref == 'refs/heads/citest' }}
- name: Build and push
id: push
uses: docker/build-push-action@5176d81f87c23d6fc96624dfdbcd9f3830bbe445 # v6.5.0
with:
context: release/docker
platforms: linux/amd64,linux/arm64
push: true
provenance: false
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
annotations: ${{ steps.meta.outputs.annotations }}
- uses: actions/attest-build-provenance@v1
with:
subject-name: ghcr.io/${{ github.repository }}
subject-digest: ${{ steps.push.outputs.digest }}
deploy:
# This action has access to our AWS keys, so we are extra careful here.

View File

@ -11,6 +11,8 @@
([#7045](https://github.com/mitmproxy/mitmproxy/pull/7045), @mhils)
- Fix UDP error handling when we learn that the remote has disconnected.
([#7045](https://github.com/mitmproxy/mitmproxy/pull/7045), @mhils)
- Container images are now published to both Docker Hub and GitHub Container Registry.
([#7061](https://github.com/mitmproxy/mitmproxy/pull/7061), @mhils)
## 25 July 2024: mitmproxy 10.4.0

View File

@ -1,105 +0,0 @@
#!/usr/bin/env python3
"""
Building and deploying docker images is a bit of a special snowflake as we don't get a file we can upload/download
as an artifact. So we need to do everything in one job.
"""
import os
import shutil
import subprocess
from pathlib import Path
# Security: No third-party dependencies here!
root = Path(__file__).absolute().parent.parent
ref = os.environ["GITHUB_REF"]
branch: str | None = None
tag: str | None = None
if ref.startswith("refs/heads/"):
branch = ref.replace("refs/heads/", "")
elif ref.startswith("refs/tags/"):
if not ref.startswith("refs/tags/v"):
raise AssertionError(f"Unexpected tag: {ref}")
tag = ref.replace("refs/tags/v", "")
else:
raise AssertionError("Failed to parse $GITHUB_REF")
(whl,) = root.glob("release/dist/mitmproxy-*-py3-none-any.whl")
docker_build_dir = root / "release/docker"
shutil.copy(whl, docker_build_dir / whl.name)
# Build for this platform and test if it runs.
subprocess.check_call(
[
"docker",
"buildx",
"build",
"--tag",
"localtesting",
"--load",
"--build-arg",
f"MITMPROXY_WHEEL={whl.name}",
".",
],
cwd=docker_build_dir,
)
r = subprocess.run(
[
"docker",
"run",
"--rm",
"-v",
f"{root / 'release'}:/release",
"localtesting",
"mitmdump",
"-s",
"/release/selftest.py",
],
capture_output=True,
)
print(r.stdout.decode())
assert "Self-test successful" in r.stdout.decode()
assert r.returncode == 0
# Now we can deploy.
subprocess.check_call(
[
"docker",
"login",
"-u",
os.environ["DOCKER_USERNAME"],
"-p",
os.environ["DOCKER_PASSWORD"],
]
)
def _buildx(docker_tag):
subprocess.check_call(
[
"docker",
"buildx",
"build",
"--tag",
docker_tag,
"--push",
"--platform",
"linux/amd64,linux/arm64",
"--build-arg",
f"MITMPROXY_WHEEL={whl.name}",
".",
],
cwd=docker_build_dir,
)
if branch == "main":
_buildx("mitmproxy/mitmproxy:dev")
elif branch == "citest":
_buildx("mitmproxy/mitmproxy:citest")
elif tag:
_buildx(f"mitmproxy/mitmproxy:{tag}")
_buildx("mitmproxy/mitmproxy:latest")
else:
raise AssertionError

View File

@ -1,8 +1,7 @@
FROM python:3.11-bullseye as wheelbuilder
FROM python:3.11-bullseye AS wheelbuilder
ARG MITMPROXY_WHEEL
COPY $MITMPROXY_WHEEL /wheels/
RUN pip install wheel && pip wheel --wheel-dir /wheels /wheels/${MITMPROXY_WHEEL}
COPY mitmproxy-*-py3-none-any.whl /wheels/
RUN pip install wheel && pip wheel --wheel-dir /wheels /wheels/*.whl
FROM python:3.11-slim-bullseye

View File

@ -2,5 +2,4 @@
1. Copy `mitmproxy-$VERSION-py3-none-any.whl` into this directory.
You can get the latest public release at https://mitmproxy.org/downloads/.
2. Replace $VERSION with your mitmproxy version and
run `docker build --build-arg MITMPROXY_WHEEL=mitmproxy-$VERSION-py3-none-any.whl .`.
2. Run `docker build .`.