diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9fd76bc..d6e6db9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,8 +1,12 @@ # we support merge request workflow only include: - - template: 'Workflows/MergeRequest-Pipelines.gitlab-ci.yml' - local: '.gitlab/ci/*.yml' +workflow: + rules: + - if: $CI_MERGE_REQUEST_IID + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + default: image: ${BASE_BUILD_REGISTRY_IMAGE}/debian-bullseye-slim:docker-20.10.14-buildx-0.8 services: @@ -22,14 +26,7 @@ stages: variables: DOCKER_HOST: tcp://docker:2375 + BASE_BUILD_REGISTRY_IMAGE: registry.gitlab.com/gitlab-org/gitlab-build-images -cache-google-chrome: - image: debian:bullseye-slim - stage: automation - # Starts the job immediately - needs: [] - script: - - bash ./scripts/cache-google-chrome - # disable DinD - before_script: [] - services: [] +cache-chrome-chromium: + extends: .cache-google-chrome diff --git a/.gitlab/ci/definitions.yml b/.gitlab/ci/definitions.yml index c8c0a87..7e591c4 100644 --- a/.gitlab/ci/definitions.yml +++ b/.gitlab/ci/definitions.yml @@ -1,32 +1,60 @@ -.build_and_push: - stage: custom - needs: [] +.install-qemu: + timeout: 2 hours # builds with emulation can take a long time to complete tags: - docker - high-cpu variables: QEMU_IMAGE: tonistiigi/binfmt:qemu-v6.2.0 - timeout: 2 hours before_script: - - echo "$CI_REGISTRY_PASSWORD" | docker login "$CI_REGISTRY" -u "$CI_REGISTRY_USER" --password-stdin - | - if [ "${ARCH:-amd64}" != "amd64" ]; then + if [ "$PUSH_CUSTOM_IMAGE" == "true" ]; then + echo "$CI_REGISTRY_PASSWORD" | docker login "$CI_REGISTRY" -u "$CI_REGISTRY_USER" --password-stdin + fi + - | + if [[ "${ARCH:-amd64}" =~ arm64 ]]; then echo -e "\033[1;33mInstalling latest qemu emulators\033[0m" docker pull -q ${QEMU_IMAGE}; docker run --rm --privileged ${QEMU_IMAGE} --uninstall qemu-*; docker run --rm --privileged ${QEMU_IMAGE} --install all; fi + +.build_and_push: + stage: custom + extends: .install-qemu + needs: [] script: - ./scripts/lib/custom-docker-build rules: - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_SERVER_HOST == "gitlab.com"' - variables: - BASE_BUILD_REGISTRY_IMAGE: registry.gitlab.com/gitlab-org/gitlab-build-images - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_SERVER_HOST == "gitlab.com"' variables: PUSH_CUSTOM_IMAGE: "true" - BASE_BUILD_REGISTRY_IMAGE: registry.gitlab.com/gitlab-org/gitlab-build-images - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && ($CI_SERVER_HOST == "ops.gitlab.net" || $CI_SERVER_HOST == "dev.gitlab.org")' variables: PUSH_CUSTOM_IMAGE: "true" BASE_BUILD_REGISTRY_IMAGE: $CI_REGISTRY_IMAGE + +.cache-google-chrome: + stage: automation + extends: .install-qemu + needs: [] + variables: + ARCH: linux/amd64,linux/arm64 + before_script: + - !reference [.install-qemu, before_script] + - docker buildx create --use # creates context that's capable of building multiple architectures in parallel + script: + - | + docker buildx build \ + --build-arg CI_API_V4_URL=$CI_API_V4_URL \ + --build-arg CI_PROJECT_ID=$CI_PROJECT_ID \ + --build-arg CI_JOB_TOKEN=$CI_JOB_TOKEN \ + --platform $ARCH \ + -f "Dockerfile.cache-chrome" \ + . + rules: + - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_SERVER_HOST == "gitlab.com"' + - if: '$CI_PIPELINE_SOURCE == "schedule" && $CI_SERVER_HOST == "gitlab.com"' + - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_SERVER_HOST == "gitlab.com"' + when: manual + allow_failure: true diff --git a/.gitlab/ci/e2e.images.yml b/.gitlab/ci/e2e.images.yml index ac51be2..50c6e5c 100644 --- a/.gitlab/ci/e2e.images.yml +++ b/.gitlab/ci/e2e.images.yml @@ -23,7 +23,7 @@ e2e-chrome: extends: - e2e-docker variables: - CHROME: '103' + CHROME: '104' parallel: matrix: - RUBY: ['2.7', '3.0'] diff --git a/Dockerfile.cache-chrome b/Dockerfile.cache-chrome new file mode 100644 index 0000000..5e1d45c --- /dev/null +++ b/Dockerfile.cache-chrome @@ -0,0 +1,11 @@ +# Save amd64 chrome and arm64 .deb files to package registry +FROM debian:latest + +ARG TARGETARCH +ARG CI_API_V4_URL +ARG CI_PROJECT_ID +ARG CI_JOB_TOKEN + +ADD scripts/cache-google-chrome /cache-google-chrome + +RUN /cache-google-chrome diff --git a/scripts/cache-google-chrome b/scripts/cache-google-chrome index a148ba8..e08bd4c 100755 --- a/scripts/cache-google-chrome +++ b/scripts/cache-google-chrome @@ -1,47 +1,86 @@ #!/bin/bash + # This script attempts to copy the latest version of the Google Chrome Debian # package into our own package registry. Google yanks old versions regularly, # making it hard to keep up with all the new versions. set -e -PKG=google-chrome-stable - export DEBIAN_FRONTEND=noninteractive -apt-get -y update -apt-get -y install apt-utils curl bash gnupg2 -curl -sS -L https://dl.google.com/linux/linux_signing_key.pub | apt-key add - -echo "deb [arch=$(dpkg --print-architecture)] http://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google.list +function save-package() { + local PKG=$1 + local DEB=$2 + local LATEST_VERSION=$3 + local REGISTRY_PACKAGE=${4:-$PKG} + local SOURCE_DEB=${5:-$DEB} -echo "Updating apt to get Google Chrome packages..." + local URL="${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/${REGISTRY_PACKAGE}/${LATEST_VERSION}/${DEB}" -apt-get -y -q update + echo "Checking if ${PKG} v${LATEST_VERSION} is already cached" + local FILE_CHECK=$(curl --silent --location --head --output /dev/null --write "%{http_code}\\n" "$URL") -echo "Checking for latest Chrome version in apt repository..." + if [ "$FILE_CHECK" -eq "200" ]; then + echo "${PKG} v${LATEST_VERSION} is already cached!" + else + echo "Downloading latest ${PKG} version (${LATEST_VERSION}) from apt repository..." + cd /tmp + apt-get download "$PKG" -LATEST_VERSION=$(apt-cache show $PKG | grep Version | sort | tail -1 | sed -e "s/Version: //") -CHROME_DEB="google-chrome-stable_${LATEST_VERSION}_$(dpkg --print-architecture).deb" -CHROME_URL="${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/${PKG}/${LATEST_VERSION}/${CHROME_DEB}" + if ! [ -f "${SOURCE_DEB}" ]; then + echo "Downloaded file didn't have expected name: ${SOURCE_DEB}" + ls + exit 1 + fi -echo "Checking if cache has $CHROME_DEB" -FILE_CHECK=$(curl --silent --location --head --output /dev/null --write "%{http_code}\\n" "$CHROME_URL") + if [ "$SOURCE_DEB" != "$DEB" ]; then + mv "$SOURCE_DEB" "$DEB" + fi -if [ "$FILE_CHECK" -eq "200" ]; then - echo "Latest version $LATEST_VERSION is already cached!" -else - echo "Downloading latest Chrome version ($LATEST_VERSION) in apt repository..." - cd /tmp - apt-get download $PKG - - if ! [ -f "$CHROME_DEB" ]; then - echo "Downloaded file didn't have expected name: $CHROME_DEB" - ls - exit 1 + echo "Transferring ${PKG} v${LATEST_VERSION} to GitLab packages" + curl --fail --header "JOB-TOKEN: ${CI_JOB_TOKEN}" \ + --upload-file "./{$DEB}" \ + "$URL" fi +} - echo "Transferring $CHROME_DEB to GitLab packages" - curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" \ - --upload-file "./{$CHROME_DEB}" \ - "$CHROME_URL" +function cache-chrome() { + PKG=google-chrome-stable + + echo "Updating apt to get Google Chrome packages..." + curl -sS -L https://dl.google.com/linux/linux_signing_key.pub | apt-key add - + echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >/etc/apt/sources.list.d/google.list + apt-get -y -qq update + + echo "Checking for latest '${PKG}' version in apt repository..." + LATEST_VERSION=$(apt-cache show $PKG | grep Version | sort | tail -1 | sed -e "s/Version: //") + CHROME_DEB="google-chrome-stable_${LATEST_VERSION}_amd64.deb" + + save-package "$PKG" "$CHROME_DEB" "$LATEST_VERSION" +} + +function cache-chromium() { + PKG=chromium + PKG_DRIVER=chromium-driver + + echo "Checking for latest '${PKG}' version in apt repository..." + LATEST_VERSION=$(apt-cache show $PKG | grep Version | sort | tail -1 | sed -e "s/Version: //") + VERSION_NUMBER=$(echo $LATEST_VERSION | sed -e "s/~deb.*//") # remove debian version part to have chrome and chromium compatible version numbers + CHROMIUM_DEB="${PKG}_${VERSION_NUMBER}_${TARGETARCH}.deb" + CHROMIUM_DRIVER_DEB="${PKG_DRIVER}_${VERSION_NUMBER}_${TARGETARCH}.deb" + + # Save both chromium and chromium-driver under the same package + save-package "$PKG" "$CHROMIUM_DEB" "$VERSION_NUMBER" "${PKG}" "${PKG}_${LATEST_VERSION}_${TARGETARCH}.deb" + save-package "$PKG_DRIVER" "$CHROMIUM_DRIVER_DEB" "$VERSION_NUMBER" "${PKG}" "${PKG_DRIVER}_${LATEST_VERSION}_${TARGETARCH}.deb" +} + +echo "Updating system utils" +apt-get -y -qq update +apt-get -y install apt-utils curl gnupg2 >/dev/null + +if [ "$TARGETARCH" == "amd64" ]; then + cache-chrome + cache-chromium +else + cache-chromium fi diff --git a/scripts/install-chrome b/scripts/install-chrome index 32bec58..3b0e7e5 100755 --- a/scripts/install-chrome +++ b/scripts/install-chrome @@ -4,57 +4,45 @@ set -xeuo pipefail IFS=$'\n\t' function build_debian() { - ARCH="${TARGETARCH:-amd64}" + CHROME_VERSION=${1:-103.0.5060.134-1} + ARCH=${TARGETARCH:-amd64} - if [[ "${ARCH}" == "arm64" ]]; then - echo "The arm64 does not have prebuilt chrome. Using chromium instead." - apt-get update -q -y - apt-get install -y chromium chromium-driver - apt-get autoremove -yq - apt-get clean -yqq - rm -rf /var/lib/apt/lists/* - exit 0 + if [ "${ARCH}" == "amd64" ]; then + PKG=google-chrome-stable + else + PKG=chromium fi - CHROME_VERSION=${1:-99.0.4844.74-1} # We hard code the URL rather than using $CI_API_V4_URL $CI_PROJECT_ID, # because we would need to forward those variables - CHROME_DOWNLOAD_URL_BASE="https://gitlab.com/api/v4/projects/1075790/packages/generic/google-chrome-stable" - export DEBIAN_FRONTEND=noninteractive + DOWNLOAD_URL_BASE="https://gitlab.com/api/v4/projects/1075790/packages/generic/${PKG}" + BROWSER_DEB="${PKG}_${CHROME_VERSION}_${ARCH}.deb" + BROWSER_URL="${DOWNLOAD_URL_BASE}/${CHROME_VERSION}/${BROWSER_DEB}" - curl -sS -L https://dl.google.com/linux/linux_signing_key.pub | apt-key add - - echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >/etc/apt/sources.list.d/google.list + echo "Installing browser" + curl --silent --show-error --fail -O "$BROWSER_URL" + dpkg -i "./${BROWSER_DEB}" || true + apt-get install -f -y + rm -f "$BROWSER_DEB" - apt-get update -q -y + echo "Installing webdriver" + if [ "${ARCH}" == "amd64" ]; then + CHROME_VERSION_BASE=$(echo $CHROME_VERSION | awk -F "." '{print $1 "." $2 "." $3}') + CHROME_DRIVER_VERSION=$(curl -q https://chromedriver.storage.googleapis.com/LATEST_RELEASE_$CHROME_VERSION_BASE) - # Download from our package registry if we can't find the package in the apt repository - echo "Searching for $CHROME_VERSION in apt repository" - CHECK_VERSION=$(apt-cache show google-chrome-stable | grep Version | grep "$CHROME_VERSION") || true - - apt-cache policy google-chrome-stable - - if [[ -z $CHECK_VERSION ]]; then - CHROME_DEB="google-chrome-stable_${CHROME_VERSION}_${ARCH}.deb" - CHROME_URL="${CHROME_DOWNLOAD_URL_BASE}/${CHROME_VERSION}/${CHROME_DEB}" - echo "Downloading from our Package registry: $CHROME_URL" - curl --silent --show-error --fail -O $CHROME_URL - dpkg -i ./$CHROME_DEB || true - apt-get install -f -y - rm -f $CHROME_DEB + wget -q https://chromedriver.storage.googleapis.com/$CHROME_DRIVER_VERSION/chromedriver_linux64.zip + unzip chromedriver_linux64.zip -d /usr/local/bin + rm -f chromedriver_linux64.zip else - echo "Installing via apt-get" - apt-get install -y google-chrome-stable=$CHROME_VERSION + DRIVER_DEB="${PKG}-driver_${CHROME_VERSION}_${ARCH}.deb" + DRIVER_URL="${DOWNLOAD_URL_BASE}/${CHROME_VERSION}/${DRIVER_DEB}" + + curl --silent --show-error --fail -O "$DRIVER_URL" + dpkg -i "./${DRIVER_DEB}" || true + apt-get install -f -y + rm -f "$DRIVER_DEB" fi - rm -rf /var/lib/apt/lists/* - - # Install ChromeDriver - CHROME_VERSION_BASE=$(echo $CHROME_VERSION | awk -F "." '{print $1 "." $2 "." $3}') - CHROME_DRIVER_VERSION=$(curl -q https://chromedriver.storage.googleapis.com/LATEST_RELEASE_$CHROME_VERSION_BASE) - wget -q https://chromedriver.storage.googleapis.com/$CHROME_DRIVER_VERSION/chromedriver_linux64.zip - unzip chromedriver_linux64.zip -d /usr/local/bin - rm -f chromedriver_linux64.zip - apt-get autoremove -yq apt-get clean -yqq rm -rf /var/lib/apt/lists/* diff --git a/scripts/lib/custom-docker-build b/scripts/lib/custom-docker-build index 6465450..8d49b8f 100755 --- a/scripts/lib/custom-docker-build +++ b/scripts/lib/custom-docker-build @@ -54,6 +54,9 @@ function print_chrome_args() { 103|103.0) CHROME_VERSION=103.0.5060.114-1 ;; + 104|104.0) + CHROME_VERSION=104.0.5112.101-1 + ;; *) echo "Unknown chrome version $1"; exit 1; esac printf -- "--build-arg CHROME_VERSION=%s " "$CHROME_VERSION"