Skip to content

Ab/test multiarch docker #264

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

Closed
wants to merge 13 commits into from
10 changes: 10 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -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
62 changes: 62 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: "Build Docker Image"

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 from action.yml
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
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Prepare Release
name: "Action: Prepare Release"

on:
workflow_dispatch:
20 changes: 11 additions & 9 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
name: Integration Tests

on:
pull_request:
paths-ignore:
- "**.md"
push:
branches:
- master
- release/**
paths-ignore:
- "**.md"
workflow_run:
workflows:
- "Build Docker Image"
types:
- completed

env:
# Variables defined in the repository
@@ -52,6 +48,8 @@ jobs:
name: Test current action
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Create a staging release
uses: ./
@@ -87,6 +85,8 @@ jobs:
name: Mock a release
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Mock creating a Sentry release
uses: ./
@@ -105,11 +105,13 @@ jobs:
- name: Checkout directory we'll be running from
uses: actions/checkout@v4
with:
fetch-depth: 0
path: main/

- name: Checkout directory we'll be testing
uses: actions/checkout@v4
with:
fetch-depth: 0
path: test/

- name: Mock creating a Sentry release in a different directory
32 changes: 32 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -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

Check warning on line 3 in Dockerfile

GitHub Actions / Build & publish Docker images (builder, action-release-builder-image)

The 'as' keyword should match the case of the 'from' keyword

FromAsCasing: 'as' and 'FROM' keywords' casing do not match More info: https://docs.docker.com/go/dockerfile/rule/from-as-casing/

Check warning on line 3 in Dockerfile

GitHub Actions / Build & publish Docker images (app, action-release-image)

The 'as' keyword should match the case of the 'from' keyword

FromAsCasing: 'as' and 'FROM' keywords' casing do not match More info: https://docs.docker.com/go/dockerfile/rule/from-as-casing/
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

Check warning on line 15 in Dockerfile

GitHub Actions / Build & publish Docker images (builder, action-release-builder-image)

The 'as' keyword should match the case of the 'from' keyword

FromAsCasing: 'as' and 'FROM' keywords' casing do not match More info: https://docs.docker.com/go/dockerfile/rule/from-as-casing/

Check warning on line 15 in Dockerfile

GitHub Actions / Build & publish Docker images (app, action-release-image)

The 'as' keyword should match the case of the 'from' keyword

FromAsCasing: 'as' and 'FROM' keywords' casing do not match More info: https://docs.docker.com/go/dockerfile/rule/from-as-casing/
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"]
43 changes: 39 additions & 4 deletions action.yml
Original file line number Diff line number Diff line change
@@ -58,20 +58,53 @@ inputs:
runs:
using: 'composite'
steps:
# 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'
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
# via @actions/core
INPUT_ENVIRONMENT: ${{ inputs.environment }}
INPUT_INJECT: ${{ inputs.inject }}
INPUT_SOURCEMAPS: ${{ inputs.sourcemaps }}
INPUT_DIST: ${{ inputs.dist }}
INPUT_FINALIZE: ${{ inputs.finalize }}
INPUT_IGNORE_MISSING: ${{ inputs.ignore_missing }}
INPUT_IGNORE_EMPTY: ${{ inputs.ignore_empty }}
INPUT_STARTED_AT: ${{ inputs.started_at }}
INPUT_VERSION: ${{ inputs.version }}
INPUT_VERSION_PREFIX: ${{ inputs.version_prefix }}
INPUT_SET_COMMITS: ${{ inputs.set_commits }}
INPUT_PROJECTS: ${{ inputs.projects }}
INPUT_URL_PREFIX: ${{ inputs.url_prefix }}
INPUT_STRIP_COMMON_PREFIX: ${{ inputs.strip_common_prefix }}
INPUT_WORKING_DIRECTORY: ${{ inputs.working_directory }}
INPUT_DISABLE_TELEMETRY: ${{ inputs.disable_telemetry }}
INPUT_DISABLE_SAFE_DIRECTORY: ${{ inputs.disable_safe_directory }}
uses: docker://ghcr.io/getsentry/action-release-image:ab-test-multiarch-docker

# For actions running on macos or windows runners, we use a composite
# action approach which allows us to install the arch specific sentry-cli
# binary that's needed for the runner. This is slower.
- 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 +113,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 changes: 1 addition & 1 deletion dist/index.js
Original file line number Diff line number Diff line change
@@ -123585,7 +123585,7 @@ module.exports = JSON.parse('{"eN":{"H":"https://github.com/elastic/require-in-t
/***/ ((module) => {

"use strict";
module.exports = JSON.parse('{"name":"action-release","version":"1.10.5","private":true,"description":"GitHub Action for creating a release on Sentry","main":"dist/index.js","scripts":{"start":"node dist/index.js","build":"ncc build src/main.ts -e @sentry/cli","format":"prettier --write **/*.ts **/*.md","format-check":"prettier --check **/*.ts **/*.md","lint":"eslint src/**/*.ts","test":"jest","all":"yarn run format && yarn run lint && yarn run build && yarn test"},"repository":{"type":"git","url":"git+https://github.com/getsentry/action-release.git"},"keywords":["actions","sentry","release"],"author":"Sentry","license":"MIT","dependencies":{"@actions/core":"^1.11.1","@sentry/node":"^8.54.0"},"devDependencies":{"@sentry/cli":"^2.41.1","@types/jest":"^29.5.6","@types/node":"^20.8.9","@typescript-eslint/parser":"^6.9.0","@vercel/ncc":"^0.38.1","eslint":"^8.52.0","eslint-plugin-github":"^4.10.1","eslint-plugin-jest":"^27.4.3","jest":"^29.7.0","jest-circus":"^29.7.0","js-yaml":"^4.1.0","prettier":"^3.0.3","ts-jest":"^29.1.1","typescript":"^5.2.2"},"volta":{"node":"18.17.0","yarn":"1.22.4"}}');
module.exports = JSON.parse('{"name":"action-release","version":"1.10.5","private":true,"description":"GitHub Action for creating a release on Sentry","main":"dist/index.js","scripts":{"start":"node dist/index.js","build":"ncc build src/main.ts -e @sentry/cli","format":"prettier --write **/*.ts **/*.md","format-check":"prettier --check **/*.ts **/*.md","lint":"eslint src/**/*.ts","test":"jest","all":"yarn run format && yarn run lint && yarn run build && yarn test","bump-docker-tag":"./scripts/set-docker-tag.sh","bump-docker-tag-from-branch":"./scripts/set-branch-docker-tag.sh"},"repository":{"type":"git","url":"git+https://github.com/getsentry/action-release.git"},"keywords":["actions","sentry","release"],"author":"Sentry","license":"MIT","dependencies":{"@actions/core":"^1.11.1","@sentry/node":"^8.54.0","@sentry/cli":"^2.41.1"},"devDependencies":{"@types/jest":"^29.5.6","@types/node":"^20.8.9","@typescript-eslint/parser":"^6.9.0","@vercel/ncc":"^0.38.1","eslint":"^8.52.0","eslint-plugin-github":"^4.10.1","eslint-plugin-jest":"^27.4.3","jest":"^29.7.0","jest-circus":"^29.7.0","js-yaml":"^4.1.0","prettier":"^3.0.3","ts-jest":"^29.1.1","typescript":"^5.2.2"},"volta":{"node":"18.17.0","yarn":"1.22.4"}}');

/***/ })

2 changes: 2 additions & 0 deletions entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/sh -l
node /action-release/dist/index.js
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -11,7 +11,9 @@
"format-check": "prettier --check **/*.ts **/*.md",
"lint": "eslint src/**/*.ts",
"test": "jest",
"all": "yarn run format && yarn run lint && yarn run build && yarn test"
"all": "yarn run format && yarn run lint && yarn run build && yarn test",
"bump-docker-tag": "./scripts/set-docker-tag.sh",
"bump-docker-tag-from-branch": "./scripts/set-branch-docker-tag.sh"
},
"repository": {
"type": "git",
@@ -26,10 +28,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 changes: 3 additions & 0 deletions scripts/craft-pre-release.sh
100644 → 100755
Original file line number Diff line number Diff line change
@@ -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
yarn bump-docker-tag "${NEW_VERSION}"
10 changes: 10 additions & 0 deletions scripts/set-branch-docker-tag.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/bash
set -eux

# Extract the branch name from git and replace all non-alphanumerical characters with `-`
BRANCH=$(git rev-parse --abbrev-ref HEAD | sed 's/[^a-zA-Z0-9-]/-/g')

SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd $SCRIPT_DIR

./set-docker-tag.sh $BRANCH
13 changes: 13 additions & 0 deletions scripts/set-docker-tag.sh
Original file line number Diff line number Diff line change
@@ -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
Loading