-
Notifications
You must be signed in to change notification settings - Fork 11
215 lines (181 loc) · 7.74 KB
/
build.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# 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:
ref:
required: true
type: string
# 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: ${{ inputs.ref || github.ref }}
persist-credentials: false
- 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 buildMatrix = JSON.parse(fs.readFileSync("${{ github.workspace }}/repo-src/build-matrix.json"));
const {hosted, selfHosted} = buildMatrix;
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 }} ${{ matrix.container }}
runs-on: ${{ matrix.os }}
container:
image: ${{ matrix.container }}
# Access to the host filesystem is required to patch the environment for
# Alpine Linux support. See the first Alpine step below for details.
volumes:
- /:/host
steps:
- 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"
# This is how we convince GitHub Actions Runner to run an Alpine Linux
# container. We have to mask the fact that it's Alpine, install NodeJS,
# then patch the Alpine version of NodeJS in over the one that ships with
# GitHub Actions. This is because GitHub doesn't officially support
# Alpine and because they hard-code the path to NodeJS in Node-based
# actions.
# See https://github.com/actions/runner/issues/801#issuecomment-2394425757
- name: Patch native Alpine NodeJS into Runner environment
if: startsWith(matrix.container, 'alpine')
run: |
apk add nodejs
sed -i "s:^ID=alpine:ID=NotpineForGHA:" /etc/os-release
# The first path here is for GitHub-hosted workflows, while the
# second path is correct for our self-hosted workflows using the
# myoung34/github-runner container. The commands that follow this
# are correct so long as one of these paths exists.
cd /host/home/runner/runners/*/externals/ || cd /host/actions-runner/externals
rm -rf node20/*
mkdir node20/bin
ln -s /usr/bin/node node20/bin/node
shell: sh # No bash in Alpine by default
- name: Install Alpine Linux deps
if: startsWith(matrix.container, 'alpine')
run: apk add bash npm sudo
shell: sh # No bash in Alpine until after this command
- name: Install Ubuntu Linux deps
if: startsWith(matrix.container, 'ubuntu')
# Sudo is needed by the first build script, but isn't in the default
# container image for Ubuntu.
run: apt -y update && apt -y upgrade && apt -y install sudo
- uses: actions/checkout@v4
with:
path: repo-src
ref: ${{ inputs.ref || github.ref }}
persist-credentials: false
- name: Install OS packages
run: ./repo-src/build-scripts/00-packages.sh
- name: Install libvpx
run: ./repo-src/build-scripts/01-libvpx.sh
- name: Install SVT-AV1
run: ./repo-src/build-scripts/02-svt-av1.sh
- name: Install x264
run: ./repo-src/build-scripts/03-x264.sh
- name: Install x265
run: ./repo-src/build-scripts/04-x265.sh
- name: Install lame
run: ./repo-src/build-scripts/05-lame.sh
- name: Install opus
run: ./repo-src/build-scripts/06-opus.sh
- name: Install mbedtls
run: ./repo-src/build-scripts/07-mbedtls.sh
- name: Build ffmpeg and ffprobe
run: ./repo-src/build-scripts/90-ffmpeg.sh
- 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@v4
with:
name: binaries${{ env.SUFFIX }}
path: assets/*
- name: Check that executables are static
run: ./repo-src/build-scripts/99-check-static.sh
- name: Debug
uses: mxschmitt/[email protected]
with:
limit-access-to-actor: true
if: failure() && vars.ENABLE_DEBUG != ''