feat: Use hybrid approach depending on runner

This commit is contained in:
Andrei Borza
2025-02-24 10:15:42 +01:00
parent 15847b61db
commit b39c133c85
10 changed files with 166 additions and 7 deletions
+10
View File
@@ -0,0 +1,10 @@
# Docs: https://docs.docker.com/engine/reference/builder/#dockerignore-file
# These files will be ignore by Docker for COPY and ADD commands when creating a build context
# In other words, if a file should not be inside of the Docker container it should be
# added to the list, otherwise, it will invalidate cache layers and have to rebuild
# all layers after a COPY command
.git
.github
Dockerfile
.dockerignore
*.md
+61
View File
@@ -0,0 +1,61 @@
name: "build"
on:
pull_request:
types:
- opened
- synchronize
- reopened
jobs:
docker-build:
name: Build & publish Docker images
runs-on: ubuntu-latest
permissions:
packages: write
strategy:
matrix:
target:
- name: builder
image: action-release-builder-image
- name: app
image: action-release-image
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Extract docker tag
run: |
TAG=$(yq '... | select(has("uses") and .uses | test("docker://ghcr.io/getsentry/action-release-image:.*")) | .uses' action.yml | awk -F':' '{print $3}')
echo "DOCKER_TAG=$TAG" >> $GITHUB_ENV
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# BUILDKIT_INLINE_CACHE creates the image in such a way that you can
# then use --cache-from (think of a remote cache)
# This feature is allowed thanks to using the buildx plugin
#
# There's a COPY command in the builder stage that can easily invalidate the cache
# If you notice, please add more exceptions to .dockerignore since we loose the value
# of using --cache-from on the app stage
- name: Build and push
uses: docker/build-push-action@v6
with:
platforms: linux/amd64,linux/arm64
push: true
tags: ghcr.io/${{ github.repository_owner }}/${{ matrix.target.image }}:${{ env.DOCKER_TAG }}
cache-from: ghcr.io/${{ github.repository_owner }}/${{ matrix.target.image }}:master
target: ${{ matrix.target.name }}
build-args: BUILDKIT_INLINE_CACHE=1
+1 -1
View File
@@ -1,4 +1,4 @@
name: Prepare Release
name: "Action: Prepare Release"
on:
workflow_dispatch:
+32
View File
@@ -0,0 +1,32 @@
# The multi stage set up *saves* up image size by avoiding the dev dependencies
# required to produce dist/
FROM node:18-alpine as builder
WORKDIR /app
# This layer will invalidate upon new dependencies
COPY package.json yarn.lock ./
RUN export YARN_CACHE_FOLDER="$(mktemp -d)" \
&& yarn install --frozen-lockfile --quiet \
&& rm -r "$YARN_CACHE_FOLDER"
# If there's some code changes that causes this layer to
# invalidate but it shouldn't, use .dockerignore to exclude it
COPY . .
RUN yarn build
FROM node:18-alpine as app
COPY package.json yarn.lock /action-release/
# On the builder image, we install both types of dependencies rather than
# just the production ones. This generates /action-release/node_modules
RUN export YARN_CACHE_FOLDER="$(mktemp -d)" \
&& cd /action-release \
&& yarn install --frozen-lockfile --production --quiet \
&& rm -r "$YARN_CACHE_FOLDER"
# Copy the artifacts from `yarn build`
COPY --from=builder /app/dist /action-release/dist/
RUN chmod +x /action-release/dist/index.js
RUN printf '[safe]\n directory = *\n' > /etc/gitconfig
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
+33 -4
View File
@@ -58,20 +58,47 @@ inputs:
runs:
using: 'composite'
steps:
# - name: Extract tag to use for docker image
# if: runner.os == 'Linux'
# shell: bash
# run: |
# GIT_REF="${{ github.action_ref }}"
# if [[ "$GIT_REF" == refs/tags/* ]]; then
# DOCKER_TAG=${REF#refs/tags/}
# elif [[ "$GIT_REF" == refs/heads/* ]]; then
# DOCKER_TAG=${GIT_REF#refs/heads/}
# else
# DOCKER_TAG="master"
# fi
# echo "DOCKER_TAG=$DOCKER_TAG" >> $GITHUB_ENV
# For actions running on a linux runner, we use a docker
# approach as it's faster and encapsulates everything needed
# to run the action.
- name: Run docker image
if: runner.os != 'macOS' && runner.os != 'Windows'
uses: docker://ghcr.io/getsentry/action-release-image:ab/multiarch-docker
# For actions running on macos or windows runners, we use a composite
# action approach so it allows us to install the arch specific sentry-cli
# that's needed for the runner. This is slower and runners require to have
# node and npm available.
- name: Mark GitHub workspace a safe directory in git
if: ${{ inputs.disable_safe_directory != 'true' }}
if: ${{ (runner.os == 'macOS' || runner.os == 'Windows') && inputs.disable_safe_directory != 'true' }}
shell: bash
run: |
git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Get node version
- name: Get node and npm versions
if: runner.os == 'macOS' || runner.os == 'Windows'
shell: bash
run: |
echo "NODE_VERSION=$(node -v 2>/dev/null || echo '')" >> $GITHUB_ENV
echo "NPM_VERSION=$(npm -v 2>/dev/null || echo '')" >> $GITHUB_ENV
- name: Setup node
# Only install node if there isn't one already
if: env.NODE_VERSION == ''
if: ${{ (runner.os == 'macOS' || runner.os == 'Windows') && (env.NODE_VERSION == '' || env.NPM_VERSION == '') }}
uses: actions/setup-node@v4
with:
# setup-node doesn't allow absolute paths, so we can't
@@ -80,11 +107,13 @@ runs:
node-version: 18.17.0
- name: Install Sentry CLI v2
if: runner.os == 'macOS' || runner.os == 'Windows'
shell: bash
run: npm install --save-dev --no-package-lock @sentry/cli@^2.4
run: npm install --no-package-lock @sentry/cli@^2.4
working-directory: ${{ github.action_path }}
- name: Run Release Action
if: runner.os == 'macOS' || runner.os == 'Windows'
env:
# Composite actions don't pass the outer action's inputs
# down into these steps, so we have to replicate all inputs to be accessible
+2
View File
@@ -0,0 +1,2 @@
#!/bin/sh -l
node /action-release/dist/index.js
+2 -2
View File
@@ -26,10 +26,10 @@
"license": "MIT",
"dependencies": {
"@actions/core": "^1.11.1",
"@sentry/node": "^8.54.0"
"@sentry/node": "^8.54.0",
"@sentry/cli": "^2.41.1"
},
"devDependencies": {
"@sentry/cli": "^2.41.1",
"@types/jest": "^29.5.6",
"@types/node": "^20.8.9",
"@typescript-eslint/parser": "^6.9.0",
+3
View File
@@ -16,3 +16,6 @@ npm version "${NEW_VERSION}"
# The build output contains the package.json so we need to
# rebuild to ensure it's reflected after bumping the version
yarn install && yarn build
# Update the docker tag in action.yml
./scripts/set-docker-tag $NEW_VERSION
+9
View File
@@ -0,0 +1,9 @@
#!/bin/bash
set -eux
BRANCH=$(git rev-parse --abbrev-ref HEAD)
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd $SCRIPT_DIR
./set-docker-tag.sh $BRANCH
+13
View File
@@ -0,0 +1,13 @@
#!/bin/bash
set -eux
DOCKER_REGISTRY_IMAGE="docker://ghcr.io/getsentry/action-release-image"
TAG="${1}"
# Move to the project root
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd $SCRIPT_DIR/..
# We don't want the backup but this is the only way to make this
# work on macos as well
sed -i.bak -e "s|\($DOCKER_REGISTRY_IMAGE:\)[^']*|\1$TAG|" action.yml && rm -f action.yml.bak