Skip to content

MPV

MPV #5

Workflow file for this run

name: MPV
run-name: ${{ inputs.run_name }}
on:
# schedule:
# - cron: '0 12 * * *'
workflow_dispatch:
inputs:
build_target:
description: "Build target"
required: false
default: "all-64bit"
type: choice
options:
- 32bit
- 64bit
- 64bit-v3
- all-64bit
- all
needclean:
description: 'Build without cache'
required: false
default: false
type: boolean
release:
description: "Publish a release"
required: false
default: false
type: boolean
command:
description: 'input command you want to run before build'
required: false
cache_id:
description: 'input cache_id if you want to renew cache'
required: false
run_name:
description: 'The name displayed in the list of workflow runs'
required: false
# Workflow level env does not work properly in all fields.
# https://github.com/actions/runner/issues/480
env:
release: false
jobs:
# https://github.com/actions/runner/issues/480#issuecomment-1055373623
params:
runs-on: ubuntu-latest
outputs:
params: ${{ steps.env-vars.outputs.params }}
matrix: ${{ steps.script.outputs.matrix }}
steps:
- name: Generate cache_id
run: |
if [ "${{ inputs.cache_id }}" ] ; then
echo "cache_id=${{ inputs.cache_id }}" >> $GITHUB_ENV
else
echo "cache_id=$(echo $RANDOM | md5sum | head -c 20)" >> $GITHUB_ENV
fi
- id: script
uses: actions/github-script@v6
with:
script: |
const commit = await github.rest.repos.getCommit({
owner: 'mpv-player',
repo: 'mpv',
ref: `master`
})
core.exportVariable('sha', String(commit.data.sha))
let matrix = {};
let build_target = "${{ inputs.build_target }}"
switch ( build_target ) {
case "32bit":
matrix.bit = ["32"];
break;
case "64bit":
matrix.bit = ["64"];
break;
case "64bit-v3":
matrix.bit = ["64-v3"];
break;
case "all-64bit":
matrix.bit = ["64","64-v3"];
break;
case "all":
matrix.bit = ["32","64","64-v3"];
break;
default:
matrix.bit = ["64","64-v3"];
break;
}
core.setOutput("matrix",JSON.stringify(matrix));
- id: env-vars
name: Output environment variables
run: echo "params=$(echo $(jq -n 'env'))" >> $GITHUB_OUTPUT
build_mpv:
name: Build MPV
needs: params
runs-on: ubuntu-latest
container:
image: archlinux/archlinux:base-devel
continue-on-error: true
strategy:
matrix: ${{ fromJson(needs.params.outputs.matrix) }}
steps:
- name: Install Dependencies
run: |
sudo echo -e "[multilib]\nInclude = /etc/pacman.d/mirrorlist" >> /etc/pacman.conf
sudo pacman -Syu --noconfirm
sudo pacman -S --noconfirm --needed git gyp mercurial subversion ninja cmake ragel yasm nasm asciidoc enca gperf unzip xz gcc-multilib clang python-pip curl lib32-glib2 wget python-cairo
mkdir -p /home/opt/7zip
wget -qO - https://www.7-zip.org/a/7z2301-linux-x64.tar.xz | tar -xJf - -C /home/opt/7zip 7zzs
sudo ln -s /home/opt/7zip/7zzs /usr/bin/7z
pip3 install -U --break-system-packages setuptools rst2pdf mako jsonschema meson
git config --global user.name "github-actions[bot]"
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config --global pull.rebase true
git config --global rebase.autoStash true
git config --global fetch.prune true
- uses: actions/checkout@v3
- name: Checkout toolchain
uses: actions/checkout@v3
with:
repository: media-kit/libmpv-win32-video-encoders-gpl-cmake
path: mpv-winbuild-cmake
- name: Get Params
run: |
echo "sha=${{ fromJson(needs.params.outputs.params).sha }}" >> $GITHUB_ENV
echo "short_time=$(date "+%Y-%m-%d")" >> $GITHUB_ENV
echo "cache_id=${{ fromJson(needs.params.outputs.params).cache_id }}" >> $GITHUB_ENV
echo "cache_suffix=$(date "+%Y-%m-%d")-${{ fromJson(needs.params.outputs.params).sha }}-${{ fromJson(needs.params.outputs.params).cache_id }}" >> $GITHUB_ENV
- name: Restore Source Cache
if: ${{ github.event.inputs.needclean != 'true' }}
uses: actions/cache/[email protected]
id: cache_source
with:
path: ${{ github.workspace }}/mpv-winbuild-cmake/src_packages
key: ${{ runner.os }}-source-${{ env.cache_suffix }}
restore-keys: |
${{ runner.os }}-source
- name: Restore Rust Cache
if: ${{ github.event.inputs.needclean != 'true' }}
uses: actions/cache/[email protected]
id: cache_rust
with:
path: ${{ github.workspace }}/mpv-winbuild-cmake/install_rustup
key: ${{ runner.os }}-rust-${{ env.cache_suffix }}
restore-keys: |
${{ runner.os }}-rust
- name: Restore Build Cache
if: ${{ github.event.inputs.needclean != 'true' }}
uses: actions/cache/[email protected]
id: cache_build
with:
path: ${{ github.workspace }}/mpv-winbuild-cmake/build${{ matrix.bit }}
key: ${{ runner.os }}-mpv-build${{ matrix.bit }}-${{ env.cache_suffix }}
restore-keys: |
${{ runner.os }}-mpv-build${{ matrix.bit }}
- name: Running custom command
if: ${{ inputs.command != '' }}
shell: bash
continue-on-error: true
run: |
cd mpv-winbuild-cmake
bit="${{ matrix.bit }}"
gitdir=$(pwd)
buildroot=$(pwd)
srcdir=$(pwd)/src_packages
builddir=$buildroot/build$bit
if [ $bit == "32" ]; then
arch="i686"
elif [ $bit == "64" ]; then
arch="x86_64"
elif [ $bit == "64-v3" ]; then
arch="x86_64"
gcc_arch=-DGCC_ARCH=x86-64-v3
x86_64_level=-v3
fi
retry-tool() {
local RETRY_COUNTER=0
local MAX_RETRY=3
while [[ $RETRY_COUNTER -lt $MAX_RETRY ]]; do
$@ && break || sleep 2
RETRY_COUNTER=$(( $RETRY_COUNTER + 1 ))
echo "Retry $RETRY_COUNTER..."
done
if [[ $RETRY_COUNTER -ge $MAX_RETRY ]]; then
echo "Max retry count exceeded."
fi
}
set -x
${{ inputs.command }}
- name: Build
id: build
shell: bash
run: |
chmod +x build.sh
cd mpv-winbuild-cmake
if [[ "$(ls -A ../patch/*.patch)" ]]; then
for patch in ../patch/*.patch ; do
git am --3way "$patch" || git am --abort
done
fi
bash ../build.sh '${{ matrix.bit }}'
- name: Collect logs
if: ${{ always() }}
run: |
sudo 7z a logs.7z $(find mpv-winbuild-cmake/build${{ matrix.bit }} -type f -iname "*-*.log" -or -wholename "*/ffbuild/config.log")
- name: upload logs
uses: actions/upload-artifact@v3
if: ${{ always() }}
with:
name: ${{ matrix.bit }}_logs
path: logs.7z
- name: "Get artifacts' name and path"
id: get_files
uses: actions/github-script@v6
with:
script: |
const path = require('path');
const types = ["mpv-debug", "mpv-dev", "mpv"];
let arch="";
switch ( "${{ matrix.bit }}" ) {
case "32":
arch = "i686";
break;
case "64":
arch = "x86_64";
break;
case "64-v3":
arch = "x86_64-v3";
break;
}
for (let type of types) {
const globber = await glob.create(`mpv-winbuild-cmake/release/${type}-${arch}-*.7z`);
const files = await globber.glob();
if ( files.length > 0 ) {
const file = files[0];
core.exportVariable( `${type}_name`, path.basename(file) );
core.exportVariable( `${type}_path`, file );
}
}
// let { stdout: ffmpeg_hash } = await exec.getExecOutput("git -C mpv-winbuild-cmake/src_packages/ffmpeg rev-parse --short HEAD");
// ffmpeg_hash = ffmpeg_hash.trim();
// const ffmpeg_name = `ffmpeg-${arch}-git-${ffmpeg_hash}`;
// core.exportVariable( 'ffmpeg_name', ffmpeg_name );
// await exec.exec(`7z a -m0=lzma2 -mx=9 -ms=on mpv-winbuild-cmake/release/${ffmpeg_name}.7z ./mpv-winbuild-cmake/build${{ matrix.bit }}/install/mingw/bin/ffmpeg.exe`)
- name: upload mpv-debug
uses: actions/upload-artifact@v3
if: ${{ env.mpv-debug_name && env.mpv-debug_path }}
with:
name: ${{ env.mpv-debug_name }}
path: ${{ env.mpv-debug_path }}
- name: upload mpv-dev
uses: actions/upload-artifact@v3
if: ${{ env.mpv-dev_name && env.mpv-dev_path }}
with:
name: ${{ env.mpv-dev_name }}
path: ${{ env.mpv-dev_path }}
- name: upload mpv
uses: actions/upload-artifact@v3
if: ${{ env.mpv_name && env.mpv_path }}
with:
name: ${{ env.mpv_name }}
path: ${{ env.mpv_path }}
# - name: upload ffmpeg
# uses: actions/upload-artifact@v3
# if: ${{ env.ffmpeg_name }}
# with:
# name: ${{ env.ffmpeg_name }}
# path: mpv-winbuild-cmake/release/${{ env.ffmpeg_name }}.7z
- name: Save Sources Cache
if: ${{ github.ref_name == 'main' }}
uses: actions/cache/[email protected]
with:
path: ${{ github.workspace }}/mpv-winbuild-cmake/src_packages
key: ${{ runner.os }}-source-${{ env.cache_suffix }}
- name: Save Rust Cache
if: ${{ github.ref_name == 'main' }}
uses: actions/cache/[email protected]
with:
path: ${{ github.workspace }}/mpv-winbuild-cmake/install_rustup
key: ${{ runner.os }}-rust-${{ env.cache_suffix }}
- name: Save Build Cache
if: ${{ github.ref_name == 'main' }}
uses: actions/cache/[email protected]
with:
path: ${{ github.workspace }}/mpv-winbuild-cmake/build${{ matrix.bit }}
key: ${{ runner.os }}-mpv-build${{ matrix.bit }}-${{ env.cache_suffix }}
- name: "Job summary"
uses: actions/github-script@v6
continue-on-error: true
if: ${{ always() }}
with:
script: |
const path = require('path');
const { readdirSync,existsSync } = require('fs');
const myExec = async (command, args = null) => await exec.getExecOutput(command,args,{silent: true}).then(result => result.stdout.trim()).catch(err => '');
const toolchainDir = path.resolve("mpv-winbuild-cmake");
const workdir = path.resolve(toolchainDir,"src_packages");
const isGitSync = dirname => existsSync(path.join(workdir, dirname, '.git'));
const getGithubUrl = (hash,remote) => remote.replace(/\.git$/,"") + `/commit/${hash}`;
const getGitlabUrl = (hash,remote) => remote.replace(/\.git$/,"") + `/-/commit/${hash}`;
const getBitbucketUrl = (hash,remote) => remote.replace(/\.git$/,"") + `/commits/${hash}`;
const getGoogleSourceUrl = (hash,remote) => remote + `/+/${hash}`;
const gethGitVideolanUrl = (hash,remote) => remote.replace(/\/git\//,"/?p=") + `;a=commit;h=${hash}`;
const getCgitUrl = (hash,remote) => remote + `/commit/?id=${hash}`;
function getCommitUrl(hash,remote) {
let url = "";
switch (true) {
case /github\.com/.test(remote):
url = getGithubUrl(hash,remote);
break;
case /(gitlab\.com|code\.videolan\.org|gitlab\.gnome\.org)/.test(remote):
url = getGitlabUrl(hash,remote);
break;
case /bitbucket\.org/.test(remote):
url = getBitbucketUrl(hash,remote);
break;
case /googlesource\.com/.test(remote):
url = getGoogleSourceUrl(hash,remote);
break;
case /git\.videolan\.org/.test(remote):
url = gethGitVideolanUrl(hash,remote);
break;
case /git\.libssh\.org/.test(remote):
url = getCgitUrl(hash,remote);
break;
default:
url = remote;
break;
}
return url;
}
const dirs = readdirSync(workdir, { withFileTypes: true }).filter(dirent => dirent.isDirectory() && isGitSync(dirent.name) ).map(dirent => path.join(workdir, dirent.name));
let packages_table = [[{data: 'Package', header: true}, {data: 'Local commit', header: true}, {data: 'Status', header: true}, {data: 'Remote commit', header: true}]];
for (let dir of dirs) {
let local_hash = await myExec(`git -C ${dir} rev-parse --short=7 HEAD`);
let remote_branch = await myExec(`git -C ${dir} rev-parse --abbrev-ref HEAD@{upstream}`);
let remote_hash = await myExec(`git -C ${dir} rev-parse ${remote_branch}`);
let status = await myExec(`git -C ${dir} status -sb`).then(s => s.split("\n",1)[0].replace(/^## */,""));
let remote = await myExec(`git -C ${dir} config --get remote.origin.url`);
let url = getCommitUrl(remote_hash, remote);
let package_name = path.basename(dir);
packages_table.push([package_name, local_hash, status, `<a href="${url}">${remote_hash.slice(0,7)}</a>`]);
}
let toolchain_hash = await myExec(`git -C ${toolchainDir} rev-parse HEAD`);
let toolchain_remote = await myExec(`git -C ${toolchainDir} config --get remote.origin.url`);
let toolchain_url = getCommitUrl(toolchain_hash, toolchain_remote);
await core.summary
.addHeading('Basic Info')
.addRaw(`toolchain: <a href="${toolchain_url}">${toolchain_hash.slice(0,7)}</a>`,true)
.addHeading('Packages Version')
.addTable(packages_table)
.write();
publish_release:
name: Publish release
needs: [build_mpv,params]
if: ${{ (github.event.inputs.release != null && github.event.inputs.release == 'true') || (github.event.inputs.release == null && fromJson(needs.params.outputs.params).release ) }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Download artifacts
uses: actions/download-artifact@v3
with:
path: artifacts
- name: "Check artifacts"
uses: actions/github-script@v6
with:
script: |
const globber = await glob.create(`artifacts/*/mpv*.7z`);
const files = await globber.glob();
if ( files.length == 0 ) {
core.setFailed("Artifact does not exist!");
}
- name: Get current time
run: |
echo "long_time=$(date "+%Y-%m-%d %H:%M")" >> $GITHUB_ENV
echo "short_time=$(date "+%Y-%m-%d")" >> $GITHUB_ENV
- name: Commit version & remove existing tag
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
shell: bash
run: |
git fetch --tags
git checkout version || git checkout -b version origin/version || ( git checkout --orphan version && git rm -rf . )
echo -e "${{ env.short_time }}" > version
git config --global user.name "github-actions[bot]"
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add version
git diff-index --quiet HEAD || ( git commit -m "${{ env.short_time }}" && git push origin version )
if [ $(git tag -l "${{ env.short_time }}") ] ;then
gh release delete "${{ env.short_time }}" || true
git push --delete origin "${{ env.short_time }}" || true
git tag -d "${{ env.short_time }}" || true
fi
git checkout main
- name: Create release
uses: ncipollo/release-action@v1
with:
artifacts: "artifacts/*/mpv*.7z" # "artifacts/*/mpv*.7z,artifacts/*/ffmpeg*.7z"
commit: version
name: "${{ env.short_time }}"
body: "https://github.com/mpv-player/mpv/commit/${{ fromJson(needs.params.outputs.params).sha }}"
tag: "${{ env.short_time }}"
allowUpdates: true
artifactErrorsFailBuild: true
prerelease: false
token: ${{ secrets.GITHUB_TOKEN }}
- name: Prune old releases
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
shell: bash
run: |
git checkout main
bash prunetags.sh