Skip to content

Build

Build #7

Workflow file for this run

# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# A workflow to build fresh binaries.
# Builds ffmpeg and ffprobe on all OS & CPU combinations, then optionally
# attaches them to a release.
name: Build
on:
# Runs when called from another workflow, such as the release or test
# workflows.
workflow_call:
inputs:
release_id:
required: false
type: string
secrets:
# The GITHUB_TOKEN name is reserved, but not passed through implicitly.
# So we call our secret parameter simply TOKEN.
TOKEN:
required: false
# Runs on manual trigger.
workflow_dispatch:
# NOTE: The versions of the software we build are stored in versions.txt.
# By default, run all commands in a bash shell. On Windows, the default would
# otherwise be powershell. Each shell command should begin with "set -e" (to
# make any failed command fail the script immediately) and "set -x" (to log
# what commands are being run).
defaults:
run:
shell: bash
jobs:
# Configure the build matrix based on repo variables. The list of objects in
# the build matrix contents can't be changed by conditionals, but it can be
# computed by another job and deserialized. This uses
# vars.ENABLE_SELF_HOSTED to determine the build matrix, based on the
# metadata in build-matrix.json.
matrix_config:
runs-on: ubuntu-latest
outputs:
MATRIX: ${{ steps.configure.outputs.MATRIX }}
steps:
- uses: actions/checkout@v4
with:
path: repo-src
ref: ${{ github.event.pull_request.merge_commit_sha || github.event.push.head }}
- name: Configure Build Matrix
id: configure
shell: node {0}
run: |
const fs = require('fs');
const enableDebug = "${{ vars.ENABLE_DEBUG }}" != '';
const enableSelfHosted = "${{ vars.ENABLE_SELF_HOSTED }}" != '';
// Use ENABLE_SELF_HOSTED to decide what the build matrix below
// should include.
const {hosted, selfHosted} = require("${{ github.workspace }}/repo-src/build-matrix.json");
const matrix = enableSelfHosted ? hosted.concat(selfHosted) : hosted;
// Output a JSON object consumed by the build matrix below.
fs.appendFileSync(
process.env['GITHUB_OUTPUT'],
`MATRIX=${ JSON.stringify(matrix) }\n`);
// Output the debug flag directly.
fs.appendFileSync(
process.env['GITHUB_OUTPUT'],
`ENABLE_DEBUG=${ enableDebug }\n`);
// Log the outputs, for the sake of debugging this script.
console.log({enableDebug, enableSelfHosted, matrix});
# On several different hosts, build ffmpeg's dependencies, then ffmpeg itself.
# The deps are all built as static libraries.
build:
needs: matrix_config
strategy:
# Let other matrix entries complete, so we have all results on failure
# instead of just the first failure.
fail-fast: false
matrix:
include: ${{ fromJSON(needs.matrix_config.outputs.MATRIX) }}
name: Build ${{ matrix.os_name }} ${{ matrix.target_arch }}
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
with:
path: repo-src
ref: ${{ github.event.pull_request.merge_commit_sha || github.event.push.head }}
- name: Add msys2 to the Windows path
if: runner.os == 'Windows'
run: |
# At this point, we're running Git Bash. After this step, we will be
# running msys bash, just as we would be when debugging via SSH with
# mxschmitt/action-tmate.
echo "C:\\msys64\\usr\\bin" >> "$GITHUB_PATH"
echo "C:\\msys64\\mingw64\\bin" >> "$GITHUB_PATH"
- name: Install NPM for API client
if: runner.os == 'Linux'
run: sudo apt -y install npm
- name: Build in Alpine Linux for musl and static binaries without glibc
if: runner.os == 'Linux'
uses: joeyparrish/setup-alpine@0b42646c2ad2b5a0c3c645cbfa3d5cb85bd6232a
with:
branch: v3.20
shell-name: maybe-chroot
packages: bash sudo
arch: ${{ matrix.alpine_arch }}
- name: Install chroot shim for non-Linux platforms
if: runner.os != 'Linux'
run: |
# Create a dummy script with the same name as the Alpine chroot script
# above, so that all subsequent steps can refer to the same shell
# name. The name "maybe-chroot" reflects the fact that we won't
# chroot on non-Linux builds.
mkdir bin
ln -s "$SHELL" bin/maybe-chroot # macOS
ln -s "$SHELL" bin/maybe-chroot.exe # Windows
echo "$GITHUB_WORKSPACE/bin" >> "$GITHUB_PATH"
- name: Enable sudo in Alpine chroot
if: runner.os == 'Linux'
shell: maybe-chroot --root {0}
run: |
echo 'runner ALL=(ALL:ALL) NOPASSWD: ALL' > /etc/sudoers.d/runner
- name: Install OS packages
run: ./repo-src/build-scripts/00-packages.sh
shell: maybe-chroot {0}
- name: Install libvpx
run: ./repo-src/build-scripts/01-libvpx.sh
shell: maybe-chroot {0}
- name: Install SVT-AV1
run: ./repo-src/build-scripts/02-svt-av1.sh
shell: maybe-chroot {0}
- name: Install x264
run: ./repo-src/build-scripts/03-x264.sh
shell: maybe-chroot {0}
- name: Install x265
run: ./repo-src/build-scripts/04-x265.sh
shell: maybe-chroot {0}
- name: Install lame
run: ./repo-src/build-scripts/05-lame.sh
shell: maybe-chroot {0}
- name: Install opus
run: ./repo-src/build-scripts/06-opus.sh
shell: maybe-chroot {0}
- name: Install mbedtls
run: ./repo-src/build-scripts/07-mbedtls.sh
shell: maybe-chroot {0}
- name: Build ffmpeg and ffprobe
run: ./repo-src/build-scripts/08-ffmpeg.sh
shell: maybe-chroot {0}
- name: Prepare assets
run: |
set -e
set -x
mkdir assets
SUFFIX="-${{ matrix.os_name }}-${{ matrix.target_arch }}${{ matrix.exe_ext}}"
echo "SUFFIX=$SUFFIX" >> "$GITHUB_ENV"
cp ffmpeg/ffmpeg assets/ffmpeg"$SUFFIX"
cp ffmpeg/ffprobe assets/ffprobe"$SUFFIX"
# Show sizes and MD5 sums that can be verified by users later if they
# want to check for authenticity.
cd assets
wc -c *
md5sum *
# This makes it possible to debug failures in the next step by
# downloading binaries that fail the check for static linkage.
- name: Upload assets as artifacts
uses: actions/upload-artifact@v3
with:
name: binaries${{ env.SUFFIX }}
path: assets/*
- name: Check that executables are static
run: ./repo-src/build-scripts/09-check-static.sh
- name: Attach assets to release
if: inputs.release_id != ''
env:
GITHUB_TOKEN: ${{ secrets.TOKEN }}
run: |
set -e
set -x
# Attach the build outputs to the draft release. Each machine will
# do this separately and in parallel. Later, another job will take
# over to collect them all and use their MD5 sums to create the
# release notes (the "body" of the release).
release_id="${{ inputs.release_id }}"
(cd ./repo-src/api-client && npm ci)
node ./repo-src/api-client/main.js \
upload-all-assets "$release_id" assets/
- name: Debug
uses: mxschmitt/action-tmate@v3.6
with:
limit-access-to-actor: true
if: failure() && vars.ENABLE_DEBUG != ''