devops: move docker publishing to AzDO (#41724)

This commit is contained in:
Dmitry Gozman
2026-07-10 19:00:23 +01:00
committed by GitHub
parent ba4a093653
commit 615e1c7844
7 changed files with 109 additions and 94 deletions
+27 -5
View File
@@ -50,7 +50,7 @@ extends:
- task: UseNode@1
inputs:
version: '22.x'
version: '26.x'
displayName: "Install Node.js"
# Relocate the Docker data-root to the large /mnt volume: this job builds
@@ -67,13 +67,23 @@ extends:
echo '{ "data-root": "/mnt/docker" }' | sudo tee /etc/docker/daemon.json
sudo service docker start
# Register QEMU/binfmt handlers so `docker build --platform linux/arm64`
# works on the amd64 host. Equivalent to docker/setup-qemu-action@v4.
- task: Bash@3
displayName: "Set up QEMU for arm64 builds"
displayName: "setup .npmrc"
inputs:
targetType: "inline"
script: docker run --privileged --rm tonistiigi/binfmt --install arm64
script: |
echo "registry=https://devdiv.pkgs.visualstudio.com/DevDiv/_packaging/DevDiv_PublicPackages/npm/registry/" >> .npmrc
echo "registry=https://devdiv.pkgs.visualstudio.com/DevDiv/_packaging/DevDiv_PublicPackages/npm/registry/" >> tests/playwright-test/stable-test-runner/.npmrc
- task: npmAuthenticate@0
displayName: "authenticate the private npm registry"
inputs:
workingFile: .npmrc
- task: npmAuthenticate@0
displayName: "authenticate the private npm registry for stable-test-runner"
inputs:
workingFile: tests/playwright-test/stable-test-runner/.npmrc
- script: npm ci
displayName: "npm ci"
@@ -89,8 +99,20 @@ extends:
scriptLocation: "inlineScript"
inlineScript: "az acr login --name playwright"
- task: Bash@3
displayName: "Register QEMU (binfmt) for arm64 cross-build"
inputs:
targetType: "inline"
script: "docker run --rm --privileged ${ACR_CACHE_PREFIX}tonistiigi/binfmt --install arm64"
env:
ACR_CACHE_PREFIX: "playwright.azurecr.io/cached/"
- task: Bash@3
displayName: "Build & publish Docker images"
inputs:
targetType: "inline"
script: "./utils/docker/publish_docker.sh ${{ parameters.releaseChannel }}"
env:
ACR_CACHE_PREFIX: "playwright.azurecr.io/cached/"
UBUNTU_MIRROR_PREFIX: "azure."
NPMRC_SECRET: "$(Build.SourcesDirectory)/.npmrc"
@@ -1,37 +0,0 @@
name: "publish release - Docker"
on:
workflow_dispatch:
release:
types: [published]
jobs:
publish-docker-release:
name: "publish to DockerHub"
runs-on: ubuntu-22.04
permissions:
id-token: write # This is required for OIDC login (azure/login) to succeed
contents: read # This is required for actions/checkout to succeed
if: github.repository == 'microsoft/playwright'
environment: allow-publishing-docker-to-acr
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: lts/*
registry-url: 'https://registry.npmjs.org'
- name: Set up Docker QEMU for arm64 docker builds
uses: docker/setup-qemu-action@v4
with:
platforms: arm64
- run: npm ci
- run: npm run build
- name: Azure Login
uses: azure/login@v3
with:
client-id: ${{ secrets.AZURE_DOCKER_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_DOCKER_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_DOCKER_SUBSCRIPTION_ID }}
- name: Login to ACR via OIDC
run: az acr login --name playwright
- run: ./utils/docker/publish_docker.sh stable
+7 -2
View File
@@ -1,16 +1,21 @@
FROM ubuntu:jammy
ARG ACR_CACHE_PREFIX
FROM ${ACR_CACHE_PREFIX}ubuntu:jammy
ARG DEBIAN_FRONTEND=noninteractive
ARG TZ=America/Los_Angeles
ARG DOCKER_IMAGE_NAME_TEMPLATE="mcr.microsoft.com/playwright:v%version%-jammy"
ARG NODE_VERSION=24 # autogenerated via ./update-playwright-node.mjs
ARG UBUNTU_MIRROR_PREFIX
ENV LANG=C.UTF-8
ENV LC_ALL=C.UTF-8
# === INSTALL Node.js ===
RUN apt-get update && \
RUN --mount=type=secret,id=npmrc,target=/root/.npmrc,required=false \
find /etc/apt -type f \( -name '*.list' -o -name '*.sources' \) \
-exec sed -i "s|http://archive.ubuntu.com|http://${UBUNTU_MIRROR_PREFIX}archive.ubuntu.com|g; s|http://ports.ubuntu.com|http://${UBUNTU_MIRROR_PREFIX}ports.ubuntu.com|g" {} + && \
apt-get update && \
apt-get install -y curl wget gpg ca-certificates && \
mkdir -p /etc/apt/keyrings && \
curl -sL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && \
+7 -2
View File
@@ -1,16 +1,21 @@
FROM ubuntu:noble
ARG ACR_CACHE_PREFIX
FROM ${ACR_CACHE_PREFIX}ubuntu:noble
ARG DEBIAN_FRONTEND=noninteractive
ARG TZ=America/Los_Angeles
ARG DOCKER_IMAGE_NAME_TEMPLATE="mcr.microsoft.com/playwright:v%version%-noble"
ARG NODE_VERSION=24 # autogenerated via ./update-playwright-node.mjs
ARG UBUNTU_MIRROR_PREFIX
ENV LANG=C.UTF-8
ENV LC_ALL=C.UTF-8
# === INSTALL Node.js ===
RUN apt-get update && \
RUN --mount=type=secret,id=npmrc,target=/root/.npmrc,required=false \
find /etc/apt -type f \( -name '*.list' -o -name '*.sources' \) \
-exec sed -i "s|http://archive.ubuntu.com|http://${UBUNTU_MIRROR_PREFIX}archive.ubuntu.com|g; s|http://ports.ubuntu.com|http://${UBUNTU_MIRROR_PREFIX}ports.ubuntu.com|g" {} + && \
apt-get update && \
apt-get install -y curl wget gpg ca-certificates && \
mkdir -p /etc/apt/keyrings && \
curl -sL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && \
+7 -2
View File
@@ -1,16 +1,21 @@
FROM ubuntu:resolute
ARG ACR_CACHE_PREFIX
FROM ${ACR_CACHE_PREFIX}ubuntu:resolute
ARG DEBIAN_FRONTEND=noninteractive
ARG TZ=America/Los_Angeles
ARG DOCKER_IMAGE_NAME_TEMPLATE="mcr.microsoft.com/playwright:v%version%-resolute"
ARG NODE_VERSION=24 # autogenerated via ./update-playwright-node.mjs
ARG UBUNTU_MIRROR_PREFIX
ENV LANG=C.UTF-8
ENV LC_ALL=C.UTF-8
# === INSTALL Node.js ===
RUN apt-get update && \
RUN --mount=type=secret,id=npmrc,target=/root/.npmrc,required=false \
find /etc/apt -type f \( -name '*.list' -o -name '*.sources' \) \
-exec sed -i "s|http://archive.ubuntu.com|http://${UBUNTU_MIRROR_PREFIX}archive.ubuntu.com|g; s|http://ports.ubuntu.com|http://${UBUNTU_MIRROR_PREFIX}ports.ubuntu.com|g" {} + && \
apt-get update && \
# Install Node.js
apt-get install -y curl wget gpg ca-certificates && \
mkdir -p /etc/apt/keyrings && \
+13 -1
View File
@@ -37,4 +37,16 @@ else
exit 1
fi
docker build --platform "${PLATFORM}" -t "$3" -f "Dockerfile.$2" .
SECRET_ARGS=()
if [[ -n "${NPMRC_SECRET:-}" ]]; then
SECRET_ARGS+=(--secret "id=npmrc,src=${NPMRC_SECRET}")
fi
# Keep each arch image a plain single-platform manifest without the unknown/unknown platform entry.
export BUILDX_NO_DEFAULT_ATTESTATIONS=1
docker build --platform "${PLATFORM}" \
--build-arg ACR_CACHE_PREFIX="${ACR_CACHE_PREFIX}" \
--build-arg UBUNTU_MIRROR_PREFIX="${UBUNTU_MIRROR_PREFIX}" \
"${SECRET_ARGS[@]}" \
-t "$3" -f "Dockerfile.$2" .
+48 -45
View File
@@ -7,20 +7,19 @@ trap "cd $(pwd -P)" EXIT
cd "$(dirname "$0")"
MCR_IMAGE_NAME="playwright"
PW_VERSION=$(node ../../utils/workspace.js --get-version)
RELEASE_CHANNEL="$1"
if [[ "${RELEASE_CHANNEL}" == "stable" ]]; then
if [[ "${PW_VERSION}" == *-* ]]; then
echo "ERROR: cannot publish stable docker with Playwright version '${PW_VERSION}'"
exit 1
fi
elif [[ "${RELEASE_CHANNEL}" != "canary" ]]; then
echo "ERROR: unknown release channel - ${RELEASE_CHANNEL}"
if [[ "${RELEASE_CHANNEL}" != "stable" && "${RELEASE_CHANNEL}" != "canary" ]]; then
echo "ERROR: unknown release channel - '${RELEASE_CHANNEL}'"
echo "Must be either 'stable' or 'canary'"
exit 1
fi
PW_VERSION=$(node ../../utils/workspace.js --get-version)
if [[ "${RELEASE_CHANNEL}" == "stable" && "${PW_VERSION}" == *-* ]]; then
echo "ERROR: cannot publish stable docker with Playwright version '${PW_VERSION}'"
exit 1
fi
VERSION_TAG="v${PW_VERSION}"
if [[ "${RELEASE_CHANNEL}" == "canary" ]]; then
VERSION_TAG="v${PW_VERSION}-canary-$(date -u +'%Y%m%d%H%M%S')"
@@ -45,6 +44,20 @@ RESOLUTE_TAGS=(
"${VERSION_TAG}-resolute"
)
tags_for_flavor() {
local FLAVOR="$1"
if [[ "$FLAVOR" == "jammy" ]]; then
echo "${JAMMY_TAGS[@]}"
elif [[ "$FLAVOR" == "noble" ]]; then
echo "${NOBLE_TAGS[@]}"
elif [[ "$FLAVOR" == "resolute" ]]; then
echo "${RESOLUTE_TAGS[@]}"
else
echo "ERROR: unknown flavor - $FLAVOR. Must be either 'jammy', 'noble', or 'resolute'" >&2
exit 1
fi
}
tag_and_push() {
local source="$1"
local target="$2"
@@ -68,25 +81,19 @@ install_oras_if_needed() {
return
fi
local version="1.1.0"
curl -sLO "https://github.com/oras-project/oras/releases/download/v${version}/oras_${version}_linux_amd64.tar.gz"
local arch="amd64"
if [[ "$(uname -m)" == "aarch64" || "$(uname -m)" == "arm64" ]]; then
arch="arm64"
fi
curl -sLO "https://github.com/oras-project/oras/releases/download/v${version}/oras_${version}_linux_${arch}.tar.gz"
mkdir -p oras
tar -zxf oras_${version}_linux_amd64.tar.gz -C oras
rm oras_${version}_linux_amd64.tar.gz
tar -zxf oras_${version}_linux_${arch}.tar.gz -C oras
rm oras_${version}_linux_${arch}.tar.gz
}
publish_docker_images_with_arch_suffix() {
local FLAVOR="$1"
local TAGS=()
if [[ "$FLAVOR" == "jammy" ]]; then
TAGS=("${JAMMY_TAGS[@]}")
elif [[ "$FLAVOR" == "noble" ]]; then
TAGS=("${NOBLE_TAGS[@]}")
elif [[ "$FLAVOR" == "resolute" ]]; then
TAGS=("${RESOLUTE_TAGS[@]}")
else
echo "ERROR: unknown flavor - $FLAVOR. Must be either 'jammy', 'noble', or 'resolute'"
exit 1
fi
local TAGS=($(tags_for_flavor "$FLAVOR"))
local ARCH="$2"
if [[ "$ARCH" != "amd64" && "$ARCH" != "arm64" ]]; then
echo "ERROR: unknown arch - $ARCH. Must be either 'amd64' or 'arm64'"
@@ -104,17 +111,7 @@ publish_docker_images_with_arch_suffix() {
publish_docker_manifest () {
local FLAVOR="$1"
local TAGS=()
if [[ "$FLAVOR" == "jammy" ]]; then
TAGS=("${JAMMY_TAGS[@]}")
elif [[ "$FLAVOR" == "noble" ]]; then
TAGS=("${NOBLE_TAGS[@]}")
elif [[ "$FLAVOR" == "resolute" ]]; then
TAGS=("${RESOLUTE_TAGS[@]}")
else
echo "ERROR: unknown flavor - $FLAVOR. Must be either 'jammy', 'noble', or 'resolute'"
exit 1
fi
local TAGS=($(tags_for_flavor "$FLAVOR"))
for ((i = 0; i < ${#TAGS[@]}; i++)) do
local TAG="${TAGS[$i]}"
@@ -131,17 +128,23 @@ publish_docker_manifest () {
done
}
# Ubuntu 22.04
publish_docker_images_with_arch_suffix jammy amd64
publish_docker_images_with_arch_suffix jammy arm64
publish_docker_manifest jammy amd64 arm64
build_and_push_arch() {
local ARCH="$1"
publish_docker_images_with_arch_suffix jammy "${ARCH}" # Ubuntu 22.04
publish_docker_images_with_arch_suffix noble "${ARCH}" # Ubuntu 24.04
publish_docker_images_with_arch_suffix resolute "${ARCH}" # Ubuntu 26.04
}
# Ubuntu 24.04
publish_docker_images_with_arch_suffix noble amd64
publish_docker_images_with_arch_suffix noble arm64
publish_docker_manifest noble amd64 arm64
publish_manifests() {
publish_docker_manifest jammy amd64 arm64 # Ubuntu 22.04
publish_docker_manifest noble amd64 arm64 # Ubuntu 24.04
publish_docker_manifest resolute amd64 arm64 # Ubuntu 26.04
}
# Ubuntu 26.04
publish_docker_images_with_arch_suffix resolute amd64
publish_docker_images_with_arch_suffix resolute arm64
publish_docker_manifest resolute amd64 arm64
# arm64 first: its QEMU-emulated builds must run while the host is fresh. Running
# them after the native amd64 builds have churned the host triggers a qemu
# segfault in aarch64 ldconfig during libc-bin setup. amd64 is a native build and
# is unaffected by preceding work, so it goes second.
build_and_push_arch arm64
build_and_push_arch amd64
publish_manifests