Skip to content

Automated Builder

Automated Builder #625

Workflow file for this run

name: "Automated Builder"
on:
workflow_dispatch:
inputs:
binary_version:
description: "Specify the version"
required: false
binary_hash:
description: "Specify the release hash"
required: false
repository_name:
description: "Specify the repository"
required: true
repository_org:
description: "Specify the organization"
required: true
repository_dispatch:
types:
- webhook
env:
DEPOT_BINARY_HASH: "${{ inputs.binary_hash }}"
DEPOT_BINARY_VERSION: "${{ inputs.binary_version }}"
DEPOT_REPOSITORY_ORG: "${{ inputs.repository_org }}"
DEPOT_REPOSITORY_NAME: "${{ inputs.repository_name }}"
DEPOT_BUCKET_NAME: "depot"
DEPOT_BUCKET_PUBLIC_URL: "https://depot.r2.restake.cloud"
SLACK_BOT_TOKEN: "${{ secrets.SLACK_BOT_TOKEN }}"
SLACK_CHANNEL_ID: "C06QF8AKYMV"
jobs:
outputs:
name: "Outputs"
runs-on: "ubuntu-latest"
outputs:
depot_binaries: "${{ steps.set-outputs.outputs.depot_binaries }}"
depot_binary_build_name: "${{ steps.set-outputs.outputs.depot_binary_build_name }}"
depot_purpose: "${{ steps.set-outputs.outputs.depot_purpose }}"
depot_project_name: "${{ steps.set-outputs.outputs.depot_project_name }}"
depot_automatic_builds: "${{ steps.set-outputs.outputs.depot_automatic_builds }}"
depot_run_docker_build: "${{ steps.set-outputs.outputs.depot_run_docker_build }}"
depot_docker_binaries: "${{ steps.set-outputs.outputs.depot_docker_binaries }}"
depot_patches: "${{ steps.set-outputs.outputs.depot_patches }}"
depot_run_build: "${{ steps.set-outputs.outputs.depot_run_build }}"
depot_builder: "${{ steps.set-outputs.outputs.depot_builder }}"
depot_builder_version: "${{ steps.set-outputs.outputs.depot_builder_version }}"
depot_cpu: "${{ steps.set-outputs.outputs.depot_cpu }}"
steps:
- id: "checkout"
name: "Checkout code"
uses: actions/checkout@v4
- id: "setup-deno"
name: "Set up Deno"
uses: denoland/setup-deno@v1
with:
deno-version: 1.41.0
- id: "setup-envvars"
name: "Set up environment variables"
run: deno run --allow-write --allow-env --allow-read ./utils/env.ts
- id: "set-outputs"
name: "Set outputs to use in other jobs"
run: |
echo "depot_automatic_builds=${{ env.DEPOT_AUTOMATIC_BUILDS }}" >> $GITHUB_OUTPUT
echo "depot_run_docker_build=${{ env.DEPOT_RUN_DOCKER_BUILD }}" >> $GITHUB_OUTPUT
echo "depot_purpose=${{ env.DEPOT_PURPOSE }}" >> $GITHUB_OUTPUT
echo "depot_project_name=${{ env.DEPOT_PROJECT_NAME }}" >> $GITHUB_OUTPUT
echo "depot_docker_binaries=${{ env.DEPOT_DOCKER_BINARIES }}" >> $GITHUB_OUTPUT
echo "depot_patches=${{ env.DEPOT_PATCHES }}" >> $GITHUB_OUTPUT
echo "depot_run_build=${{ env.DEPOT_RUN_BUILD }}" >> $GITHUB_OUTPUT
echo "depot_builder=${{ env.DEPOT_BUILDER }}" >> $GITHUB_OUTPUT
echo "depot_builder_version=${{ env.DEPOT_BUILDER_VERSION }}" >> $GITHUB_OUTPUT
echo "depot_cpu=${{ env.DEPOT_CPU }}" >> $GITHUB_OUTPUT
printf "depot_binaries=%s\n" "${DEPOT_BINARIES//$'\n'/\\n}" >> $GITHUB_OUTPUT
printf "depot_binary_build_name=%s\n" "${DEPOT_BINARY_BUILD_NAME//$'\n'/\\n}" >> $GITHUB_OUTPUT
build:
name: "Build"
runs-on: "ubuntu-latest-l"
needs: ["outputs"]
if: ${{ needs.outputs.outputs.depot_run_build == 'true' }}
steps:
- id: "checkout"
name: "Checkout code"
uses: actions/checkout@v4
- id: "setup-deno"
name: "Set up Deno"
uses: denoland/setup-deno@v1
with:
deno-version: 1.41.0
- id: "set-builder-env"
name: "Set environment variables for build"
run: |
echo "DEPOT_BUILDER=${{ needs.outputs.outputs.depot_builder }}" >> "${GITHUB_ENV}"
echo "DEPOT_BUILDER_VERSION=${{ needs.outputs.outputs.depot_builder_version }}" >> "${GITHUB_ENV}"
echo "DEPOT_CPU=${{ needs.outputs.outputs.depot_cpu }}" >> "${GITHUB_ENV}"
echo "DEPOT_PROJECT_NAME=${{ needs.outputs.outputs.depot_project_name }}" >> "${GITHUB_ENV}"
echo "DEPOT_BINARY_BUILD_NAME=${{ needs.outputs.outputs.depot_binary_build_name }}" >> "${GITHUB_ENV}"
- id: "setup-builder-packages"
name: "Install builder packages"
run: bash ./builders/${{ env.DEPOT_BUILDER }}/deps.sh
- id: "cache-tooling"
name: "Cache tooling"
uses: "actions/cache@v4"
if: "${{ steps.setup-builder-packages.outputs.cached-tooling-key != '' }}"
with:
path: "${{ steps.setup-builder-packages.outputs.cached-tooling-path }}"
key: "${{ steps.setup-builder-packages.outputs.cached-tooling-key }}"
- id: "setup-builder"
name: "Setup builder"
run: bash ./builders/${{ env.DEPOT_BUILDER }}/setup.sh
- id: "clone-tags"
name: "Clone protocol source from tags"
uses: "actions/checkout@v4"
if: "${{ env.DEPOT_BINARY_VERSION != '' }}"
with:
repository: "${{ env.DEPOT_REPOSITORY_ORG }}/${{ env.DEPOT_REPOSITORY_NAME }}"
fetch-tags: true
path: "${{ env.DEPOT_PROJECT_NAME }}"
ref: "refs/tags/${{ env.DEPOT_BINARY_VERSION }}"
submodules: true
- id: "clone-ref"
name: "Clone protocol source from specified reference"
uses: "actions/checkout@v4"
if: "${{ env.DEPOT_BINARY_HASH != '' }}"
with:
repository: "${{ env.DEPOT_REPOSITORY_ORG }}/${{ env.DEPOT_REPOSITORY_NAME }}"
path: "${{ env.DEPOT_PROJECT_NAME }}"
ref: "${{ env.DEPOT_BINARY_HASH }}"
fetch-depth: 1
submodules: true
- id: "apply-patches"
name: "Apply patches"
if: ${{ needs.outputs.outputs.depot_patches == 'true' }}
run: |
set -euo pipefail
shopt -s nullglob
cd "${GITHUB_WORKSPACE}/${{ env.DEPOT_PROJECT_NAME }}"
git am --3way "${GITHUB_WORKSPACE}/patches/${{ env.DEPOT_PROJECT_NAME }}"/*.patch
- id: "build-binaries"
name: "Run protocol-specific build script"
run: bash "./scripts/${{ env.DEPOT_PROJECT_NAME }}/build.sh"
- id: "generate-checksum"
name: "Generate checksum file"
run: |
cd ${{ env.DEPOT_PROJECT_NAME }}/bin
sha256sum * > SHA256SUMS
- id: "upload-artifacts"
name: "Save binary to workspace"
uses: "actions/upload-artifact@v4"
with:
name: "binaries"
path: "${{ env.DEPOT_PROJECT_NAME }}/bin/*"
if-no-files-found: "error"
retention-days: 1
upload:
name: "Upload"
needs: [ "build", "outputs" ]
runs-on: "ubuntu-latest"
if: ${{ needs.outputs.outputs.depot_automatic_builds == 'true' || github.event_name == 'workflow_dispatch' }}
steps:
- id: "checkout"
name: "Checkout code"
uses: actions/checkout@v4
- id: "download-artifacts"
name: "Download binaries from workspace"
uses: "actions/download-artifact@v4"
with:
name: "binaries"
path: "binaries"
- id: "setup-rclone"
name: "Set up rclone CLI"
run: curl https://rclone.org/install.sh | sudo bash
- id: "setup-rclone-config"
name: "Set up rclone config"
run: printf "%s" "${{ secrets.R2_CONFIG }}" > rclone.conf
- id: "upload-binary"
name: "Upload binary to R2 bucket and verify a successful upload"
run: |
set -euo pipefail
VERSION="${DEPOT_BINARY_VERSION:-SHA-$DEPOT_BINARY_HASH}"
for file in binaries/*; do
if [ -f "$file" ]; then
filename=$(basename "$file")
directory="${{ needs.outputs.outputs.depot_purpose }}/${{ needs.outputs.outputs.depot_project_name }}/${VERSION}"
rclone --config="rclone.conf" copy "$file" "r2:${{ env.DEPOT_BUCKET_NAME }}/${directory}"
status_code=$(curl -sL -w "%{http_code}\\n" "${{ env.DEPOT_BUCKET_PUBLIC_URL }}/${directory}/${filename}" -o /dev/null)
if [ "$status_code" -ne 200 ]; then
echo "Error: Binary $filename is not downloadable (HTTP status code $status_code)"
exit 1
fi
fi
done
docker:
name: "Build and Publish Docker"
runs-on: "ubuntu-latest-l"
needs: [ "outputs", "build" ]
if: ${{ needs.outputs.outputs.depot_run_docker_build == 'true' && (always() && !failure() && !cancelled()) }}
steps:
- id: "checkout"
name: "Checkout repository"
uses: actions/checkout@v4
- id: "download-binaries"
name: "Download binaries artifact"
if: ${{ needs.outputs.outputs.depot_run_build == 'true' }}
uses: actions/download-artifact@v4
with:
name: "binaries"
path: "binaries"
- id: "set-docker-env"
name: "Set environment variables for Docker"
run: |
echo "DEPOT_PROJECT_NAME=${{ needs.outputs.outputs.depot_project_name }}" >> "${GITHUB_ENV}"
VERSION="${DEPOT_BINARY_VERSION:-$DEPOT_BINARY_HASH}"
echo "DEPOT_BINARY_VERSION=${VERSION}" >> "${GITHUB_ENV}"
project_dockerfile="docker/${{ needs.outputs.outputs.depot_project_name }}.Dockerfile"
if [ -f "${project_dockerfile}" ]; then
echo "DEPOT_DOCKERFILE=${project_dockerfile}" >> "${GITHUB_ENV}"
else
echo DEPOT_DOCKERFILE="docker/default.Dockerfile" >> "${GITHUB_ENV}"
fi
- id: "login-ghcr"
name: "Log in to the Container registry"
uses: "docker/[email protected]"
with:
registry: "ghcr.io"
username: "restake-bot"
password: "${{ secrets.RESTAKE_BOT_TOKEN }}"
- id: "build-docker"
name: "Build and push Docker image"
uses: docker/build-push-action@v5
with:
context: .
file: "${{ env.DEPOT_DOCKERFILE }}"
build-args: |
DEPOT_BINARY_VERSION=${{ env.DEPOT_BINARY_VERSION }}
DEPOT_DOCKER_BINARIES=${{ needs.outputs.outputs.depot_docker_binaries }}
platforms: "linux/amd64"
push: true
no-cache: true
tags: |
ghcr.io/restake/depot/${{ env.DEPOT_PROJECT_NAME }}:${{ env.DEPOT_BINARY_VERSION }}
notify-binary:
name: "Notify binary build success on Slack"
runs-on: "ubuntu-latest"
needs: ["build", "upload", "outputs"]
if: ${{ needs.outputs.outputs.depot_automatic_builds == 'true' && needs.build.result == 'success' || needs.upload.result == 'success' || needs.build.result != 'success' || needs.upload.result != 'success' }}
steps:
- id: "get-workflow-url"
name: "Get workflow URL"
run: |
workflow_url="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}"
echo "WORKFLOW_URL=${workflow_url}" >> "${GITHUB_ENV}"
echo "DEPOT_BINARY_NAMES=${{ needs.outputs.outputs.depot_binaries }}" >> "${GITHUB_ENV}"
- id: "checkout"
name: "Checkout code"
uses: actions/checkout@v4
- id: "slack-notify-failure"
name: "Notify on Slack upon failure"
if: "${{ needs.build.result != 'success' || needs.upload.result != 'success' }}"
uses: slackapi/[email protected]
with:
channel-id: "${{ env.SLACK_CHANNEL_ID }}"
payload-file-path: "./templates/notify-failure.json"
- id: "slack-notify-success"
name: "Notify on Slack upon success"
if: "${{ needs.build.result == 'success' && needs.upload.result == 'success' }}"
uses: slackapi/[email protected]
with:
channel-id: "${{ env.SLACK_CHANNEL_ID }}"
payload-file-path: "./templates/notify-success.json"
notify-docker:
name: "Notify Docker image build on Slack"
runs-on: "ubuntu-latest"
needs: ["docker", "outputs"]
if: ${{ needs.outputs.outputs.depot_run_docker_build == 'true' && needs.docker.result == 'success' && (always() && !failure() && !cancelled()) }}
outputs:
docker-status: "${{ needs.docker.result }}"
steps:
- id: "set-project-name"
name: "Set project name to envvar"
run: echo "DEPOT_PROJECT_NAME=${{ needs.outputs.outputs.depot_project_name }}" >> "${GITHUB_ENV}"
- id: "checkout"
name: "Checkout code"
uses: actions/checkout@v4
- id: "slack-notify-docker"
name: "Notify Docker image build on Slack"
uses: slackapi/[email protected]
with:
channel-id: "${{ env.SLACK_CHANNEL_ID }}"
payload-file-path: "./templates/notify-docker.json"