Skip to content

Support using an Older Chrome Release #25

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ FROM --platform=linux/amd64 heroku/heroku:${STACK_VERSION}-build as build
ARG STACK_VERSION
ENV STACK="heroku-${STACK_VERSION}"

ARG GOOGLE_CHROME_MILESTONE_OFFSET

# On Heroku-24 and later the default user is not root.
# Once support for Heroku-22 and older is removed, the `useradd` steps below can be removed.
USER root
Expand All @@ -15,6 +17,9 @@ USER non-root-user
RUN mkdir -p /tmp/build /tmp/cache /tmp/env
COPY --chown=non-root-user . /buildpack

# Emulate the platform providing app config vars via env directory
RUN if [ -n "${GOOGLE_CHROME_MILESTONE_OFFSET}" ]; then echo "${GOOGLE_CHROME_MILESTONE_OFFSET}" > /tmp/env/GOOGLE_CHROME_MILESTONE_OFFSET; fi

# Sanitize the environment seen by the buildpack, to prevent reliance on
# environment variables that won't be present when it's run by Heroku CI.
RUN env -i PATH=$PATH HOME=$HOME STACK=$STACK /buildpack/bin/detect /tmp/build
Expand Down
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,25 @@ by [Google](https://googlechromelabs.github.io/chrome-for-testing/).
You can control the channel of the release by setting the `GOOGLE_CHROME_CHANNEL`
config variable to `Stable`, `Beta`, `Dev`, or `Canary`, and then deploy/build the app.

## Using an Older Chrome Release

If the most recent stable Chrome or Chromedriver release has problems, perhaps due to an
app dependecy like Selenium not being compatible yet, an older major release can be installed.

You can control how many major versions (milestones) back to install, with
`GOOGLE_CHROME_MILESTONE_OFFSET` config variable.

*This version offset strategy does not lock the app to a specific Chrome version. It will still update automatically, but lag behind by the specified offset.*

Set `GOOGLE_CHROME_MILESTONE_OFFSET` to a negative index, such as:
* `-4` for the previous major stable release
* `-3` for the current major stable release
* `-2` for the beta release
* `-1` for the dev release.

During build, this offset indexes the milestone-sorted data returned from the Chrome for Testing API [`latest-versions-per-milestone.json`](https://googlechromelabs.github.io/chrome-for-testing/latest-versions-per-milestone.json),
in order to resolve a specific version to install.

## Migrating from Separate Buildpacks

### Remove Existing Installations
Expand Down
47 changes: 37 additions & 10 deletions bin/compile
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,44 @@ if which chrome; then
error "Chrome is already installed. This buildpack now installs a compatible version of Chrome. Please, remove the other Chrome installation. Chrome may have been installed by another buildpack (such as heroku/heroku-buildpack-google-chrome buildpack), which should no longer be used with this buildpack."
fi

# Detect requested channel or default to stable
if [ -f "$ENV_DIR/GOOGLE_CHROME_CHANNEL" ]; then
channel=$(cat "$ENV_DIR/GOOGLE_CHROME_CHANNEL")
echo "Using env var GOOGLE_CHROME_CHANNEL=$channel" | indent
# Detect milestone offset or channel-based version selection
if [ -f "$ENV_DIR/GOOGLE_CHROME_MILESTONE_OFFSET" ]; then
milestone_offset=$(cat "$ENV_DIR/GOOGLE_CHROME_MILESTONE_OFFSET")
echo "Using env var GOOGLE_CHROME_MILESTONE_OFFSET=$milestone_offset" | indent

# jq is required to parse Chrome for Testing JSON API response
if which jq; then
echo "Using existing jq" | indent
else
echo "Installing jq" | indent
JQ_DIR="$INSTALL_DIR/jq"
mkdir -p "$JQ_DIR"
cd "$JQ_DIR"
wget --quiet -O jq https://github.com/jqlang/jq/releases/download/jq-1.7.1/jq-linux-$ARCH
chmod +x jq
PATH="$JQ_DIR:$PATH"
cd -
fi

latest_version_per_milestone="$(curl --silent --show-error --fail --retry 3 --retry-connrefused --connect-timeout 10 "https://googlechromelabs.github.io/chrome-for-testing/latest-versions-per-milestone.json")"
VERSION="$(echo $latest_version_per_milestone | jq --raw-output --arg milestone_offset "$milestone_offset" '.milestones | map(.) | sort_by(.milestone)[($milestone_offset | tonumber)] | .version')"
echo "Resolved milestone offset $milestone_offset to version $VERSION" | indent
INSTALLED_DESCRIPTION="milestone offset $milestone_offset"

else
channel=stable
# Detect requested channel or default to stable
if [ -f "$ENV_DIR/GOOGLE_CHROME_CHANNEL" ]; then
channel=$(cat "$ENV_DIR/GOOGLE_CHROME_CHANNEL")
echo "Using env var GOOGLE_CHROME_CHANNEL=$channel" | indent
else
channel=stable
fi
# The current version endpoint requires ALL CAPS.
CHANNEL="$(echo -n "$channel" | awk '{ print toupper($0) }')"
VERSION="$(curl --silent --show-error --fail --retry 3 --retry-connrefused --connect-timeout 10 "https://googlechromelabs.github.io/chrome-for-testing/LATEST_RELEASE_$CHANNEL")"
echo "Resolved $CHANNEL version $VERSION" | indent
INSTALLED_DESCRIPTION="$CHANNEL"
fi
# The current version endpoint requires ALL CAPS.
CHANNEL="$(echo -n "$channel" | awk '{ print toupper($0) }')"
VERSION="$(curl --silent --show-error --fail --retry 3 --retry-connrefused --connect-timeout 10 "https://googlechromelabs.github.io/chrome-for-testing/LATEST_RELEASE_$CHANNEL")"
echo "Resolved $CHANNEL version $VERSION" | indent

echo "Downloading Chrome" | indent
ZIP_URL="https://storage.googleapis.com/chrome-for-testing-public/$VERSION/linux64/chrome-linux64.zip"
Expand All @@ -83,4 +110,4 @@ export PATH="$BUILD_DIR/.chrome-for-testing/chrome-linux64:$BUILD_DIR/.chrome-fo
which chrome | indent
which chromedriver | indent

echo "Installed Chrome for Testing $CHANNEL version $VERSION" | indent
echo "Installed Chrome for Testing $INSTALLED_DESCRIPTION version $VERSION" | indent
8 changes: 8 additions & 0 deletions bin/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,11 @@ docker run --rm heroku-buildpack-chrome-for-testing bash -l -c 'chrome --no-sand

# Display a size breakdown of the directories added by the buildpack to the app.
docker run --rm heroku-buildpack-chrome-for-testing bash -l -c 'du --human-readable --max-depth=1 /app'


# Verify that the milestone offset builds too
docker build --progress=plain --build-arg="STACK_VERSION=${STACK_VERSION}" --build-arg="GOOGLE_CHROME_MILESTONE_OFFSET=-4" -t heroku-buildpack-chrome-for-testing .

# Check the profile.d scripts correctly added the binaries to PATH.
docker run --rm heroku-buildpack-chrome-for-testing bash -l -c 'chrome --version'
docker run --rm heroku-buildpack-chrome-for-testing bash -l -c 'chromedriver --version'
Loading