Skip to content

Github Actions

This project relies heavily on Github Actions to build and release the binaries. The actions are defined in the .github/workflows directory.

Github repo Actions settings

The only permissions these actions should need is:

permissions:
contents: write

These should be the default settings for recently forked versions of this repo that require this permission.

You can find these settings bu going to the repo settings/actions/general

Workflows

debian_based_CI

This workflow tests the script on x86_64 debian based systems and produces some artifcats. It’s a testing action that is not required to be run.

name: Debian Based CI
on:
# push:
# paths:
# - "qbittorrent-nox-static.sh"
# pull_request:
workflow_dispatch:
inputs:
distinct_id:
description: "Distinct id"
skip_rerun:
description: "Skip rerun?"
required: true
type: boolean
retries:
description: "Number of rerun retries"
required: true
default: "1"
type: choice
options: ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
container_id: [debian, ubuntu]
container_codename: [bookworm, jammy, noble]
qbt_build_tool: ["qmake", "cmake"]
qbt_libtorrent_version: ["1.2", "2.0"]
exclude:
- container_id: debian
container_codename: focal
- container_id: debian
container_codename: jammy
- container_id: debian
container_codename: noble
- container_id: ubuntu
container_codename: bullseye
- container_id: ubuntu
container_codename: bookworm
include:
- qbt_build_tool: "qmake"
qbt_qt_version: "5"
- qbt_build_tool: "cmake"
qbt_qt_version: "6"
name: "${{ matrix.container_id }}-${{ matrix.container_codename }}-${{ matrix.qbt_libtorrent_version }}-qt-${{ matrix.qbt_qt_version }}-${{ matrix.qbt_build_tool }}"
env:
build_dir: "qbt-build"
artifact_name: "${{ matrix.container_id }}-${{ matrix.container_codename }}-${{ matrix.qbt_libtorrent_version }}-qt-${{ matrix.qbt_qt_version }}-${{ matrix.qbt_build_tool }}-nox"
container:
image: ${{ matrix.container_id }}:${{ matrix.container_codename }}
env:
LANG: en_GB.UTF-8
DEBIAN_FRONTEND: noninteractive
TZ: Europe/London
qbt_libtorrent_version: ${{ matrix.qbt_libtorrent_version }}
qbt_qt_version: ${{ matrix.qbt_qt_version }}
qbt_build_tool: ${{ matrix.qbt_build_tool }}
qbt_cross_name: ""
qbt_patches_url: ${{ github.repository }}
qbt_skip_icu: no
qbt_boost_tag: ""
qbt_libtorrent_tag: ""
qbt_qt_tag: ""
qbt_qbittorrent_tag: ""
qbt_libtorrent_master_jamfile: no
qbt_workflow_files: yes
qbt_workflow_artifacts: no
qbt_cache_dir: ""
qbt_optimise_strip: yes
qbt_build_debug: no
qbt_revision_url: ${{ github.repository }}
steps:
- uses: actions/checkout@v4
- name: Host - update
run: apt-get update
- name: Host - upgrade
run: apt-get -y upgrade
- run: bash qbittorrent-nox-static.sh -bs-a
- run: bash qbittorrent-nox-static.sh glibc
- run: bash qbittorrent-nox-static.sh zlib
- run: bash qbittorrent-nox-static.sh iconv
- run: bash qbittorrent-nox-static.sh icu
- run: bash qbittorrent-nox-static.sh openssl
- run: bash qbittorrent-nox-static.sh boost
- run: bash qbittorrent-nox-static.sh libtorrent
- run: bash qbittorrent-nox-static.sh double_conversion
if: matrix.qbt_build_tool == 'cmake'
- run: bash qbittorrent-nox-static.sh qtbase
- run: bash qbittorrent-nox-static.sh qttools
- run: bash qbittorrent-nox-static.sh qbittorrent
- name: Host - qBittorrent v5 transition
run: |
# When qBittorrent v5 is released, remove this
if [[ -f ${{ env.qbt_build_dir }}/release_info/disable-qt5 ]]; then
printf '%s\n' "disable_qt5=yes" >> $GITHUB_ENV
fi
- name: Archive code coverage results
if: env.disable_qt5 != 'yes' # When qBittorrent v5 is released, remove this
uses: actions/upload-artifact@v4
with:
name: ${{ env.artifact_name }}
path: ${{ env.build_dir }}/completed/qbittorrent-nox
rerun-on-failure:
if: failure() && inputs.skip_rerun == '0'
name: rerun-on-failure
needs: build
permissions:
actions: write
runs-on: ubuntu-latest
env:
GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
steps:
- uses: actions/checkout@v4
- name: Trigger rerun workflow on job failures
run: |
inputs_retries="${{ inputs.retries }}"
gh workflow run rerun.yml -f run_id=${{ github.run_id }} -f attempts=${{ github.run_attempt }} -f retries=${inputs_retries:-1}
matrix_multi_build_and_release

This workflow runs the script in it’s default configuration, downloading dependencies from their normal hosted location.

# @credits https://github.com/c0re100/qBittorrent-Enhanced-Edition
name: matrix multi build and release
on:
workflow_dispatch:
inputs:
distinct_id:
description: "Distinct id"
skip_rerun:
description: "Skip rerun?"
required: true
default: true
type: boolean
retries:
description: "Number of rerun retries"
required: true
default: "1"
type: choice
options: ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
permissions:
id-token: write
contents: read
attestations: write
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
os_id: [alpine]
os_version_id: [edge]
# qbt_cross_name: [armel,armhf,armv7,aarch64,x86_64,x86,s390x,powerpc,ppc64el,mips,mipsel,mips64,mips64el,riscv64]
qbt_cross_name: ["armhf", "armv7", "aarch64", "x86_64", "x86"]
qbt_libtorrent_version: ["1.2", "2.0"]
qbt_build_tool: ["", "qmake"]
include:
- qbt_build_tool: "qmake"
qbt_qt_version_name: "qt5-"
qbt_qt_version: "5"
- qbt_build_tool: ""
qbt_qt_version_name: ""
qbt_qt_version: "6"
name: "${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}libtorrent-v${{ matrix.qbt_libtorrent_version }}"
env:
qbt_build_dir: "qbt-build"
steps:
- name: Checkout ${{ github.event.inputs.distinct_id }}
uses: actions/checkout@v4
- name: Host - phased updates ${{ github.event.inputs.distinct_id }}
run: printf '%s\n' 'APT::Get::Always-Include-Phased-Updates "false";' | sudo tee /etc/apt/apt.conf.d/99-phased-updates
- name: Host - update ${{ github.event.inputs.distinct_id }}
run: sudo apt-get update
- name: Host - upgrade ${{ github.event.inputs.distinct_id }}
run: sudo apt-get -y upgrade
- name: Host - set up qemu-user-static binfmt-support ${{ github.event.inputs.distinct_id }}
run: sudo apt install libpipeline1 qemu-user-static binfmt-support
- name: Host - Create Docker template env file ${{ github.event.inputs.distinct_id }}
run: |
printf '%s\n' "qbt_libtorrent_version=${{ matrix.qbt_libtorrent_version }}" > env.custom
printf '%s\n' "qbt_qt_version=${{ matrix.qbt_qt_version }}" >> env.custom
printf '%s\n' "qbt_build_tool=${{ matrix.qbt_build_tool }}" >> env.custom
printf '%s\n' "qbt_cross_name=${{ matrix.qbt_cross_name }}" >> env.custom
printf '%s\n' "qbt_patches_url=${{ github.repository }}" >> env.custom
printf '%s\n' "qbt_skip_icu=yes" >> env.custom
printf '%s\n' "qbt_boost_tag=" >> env.custom
printf '%s\n' "qbt_libtorrent_tag=" >> env.custom
printf '%s\n' "qbt_qt_tag=" >> env.custom
printf '%s\n' "qbt_qbittorrent_tag=" >> env.custom
printf '%s\n' "qbt_libtorrent_master_jamfile=no" >> env.custom
printf '%s\n' "qbt_workflow_files=no" >> env.custom
printf '%s\n' "qbt_workflow_artifacts=no" >> env.custom
printf '%s\n' "qbt_cache_dir=" >> env.custom
printf '%s\n' "qbt_optimise_strip=yes" >> env.custom
printf '%s\n' "qbt_build_debug=no" >> env.custom
printf '%s\n' "qbt_revision_url=${{ github.repository }}" >> env.custom
printf '%s\n' "qbt_standard=17" >> env.custom
printf '%s\n' "qbt_static_ish=no" >> env.custom
- name: Host - Create docker multiarch container ${{ github.event.inputs.distinct_id }}
run: docker run --name multiarch -it -d --env-file env.custom -w /root -v ${{ github.workspace }}:/root ${{ matrix.os_id }}:${{ matrix.os_version_id }}
- name: Docker - apk update ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch apk update
- name: Docker - apk install bash ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch apk add bash
- name: Docker - Bootstrap ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh -bs-a
- name: Docker - Copy repo patches to build folder ${{ github.event.inputs.distinct_id }}
run: if [[ -d patches ]]; then docker exec -w /root multiarch cp -r patches/* /root/${{ env.qbt_build_dir }}/patches; fi
- name: Docker - zlib-ng ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh zlib
- name: Docker - iconv ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh iconv
- name: Docker - icu ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh icu
- name: Docker - openssl ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh openssl
- name: Docker - boost ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh boost
- name: Docker - libtorrent ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh libtorrent
- name: Docker - double_conversion ${{ github.event.inputs.distinct_id }}
if: matrix.qbt_build_tool == 'cmake'
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh double_conversion
- name: Docker - qtbase ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh qtbase
- name: Docker - qttools ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh qttools
- name: Docker - qbittorrent ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh qbittorrent
- name: Host - qBittorrent v5 transition
run: |
# When qBittorrent v5 is released, remove this
if [[ -f ${{ env.qbt_build_dir }}/release_info/disable-qt5 ]]; then
printf '%s\n' "disable_qt5=yes" >> $GITHUB_ENV
fi
- name: Docker - Set release asset name ${{ github.event.inputs.distinct_id }}
if: env.disable_qt5 != 'yes' # When qBittorrent v5 is released, remove this
run: docker exec -w /root/${{ env.qbt_build_dir }}/completed multiarch mv -f qbittorrent-nox ${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}qbittorrent-nox
- name: Generate artifact attestation ${{ github.event.inputs.distinct_id }}
if: env.disable_qt5 != 'yes' # When qBittorrent v5 is released, remove this
uses: actions/attest-build-provenance@v1
with:
subject-path: "${{ env.qbt_build_dir }}/completed/${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}qbittorrent-nox"
- name: Docker - Release Info ${{ github.event.inputs.distinct_id }}
if: env.disable_qt5 != 'yes' # When qBittorrent v5 is released, remove this
run: docker exec -w /root/${{ env.qbt_build_dir }}/release_info multiarch bash -c 'mv *.md *.json '/root/${{ env.qbt_build_dir }}/completed''
# - name: Docker - upx compression ${{ github.event.inputs.distinct_id }}
# run: |
# docker exec -w /root multiarch apk add upx
# docker exec -w /root/${{ env.qbt_build_dir }}/completed multiarch upx --brute --no-lzma ${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}qbittorrent-nox
- name: Host - Upload libtorrent-v${{ matrix.qbt_libtorrent_version }}-qbittorrent-nox and release info artifact ${{ github.event.inputs.distinct_id }}
if: env.disable_qt5 != 'yes' # When qBittorrent v5 is released, remove this
uses: actions/upload-artifact@v4
with:
name: libtorrent-v${{ matrix.qbt_libtorrent_version }}-${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}qbittorrent-nox
path: |
${{ env.qbt_build_dir }}/completed/*
!${{ env.qbt_build_dir }}/completed/*.png
- name: Host - Upload cmake graphs artifact ${{ github.event.inputs.distinct_id }}
if: matrix.qbt_build_tool == 'cmake' && env.disable_qt5 != 'yes' # When qBittorrent v5 is released, remove this
uses: actions/upload-artifact@v4
with:
name: "${{ matrix.qbt_cross_name }}-libtorrent-v${{ matrix.qbt_libtorrent_version }}-graphs"
path: "${{ env.qbt_build_dir }}/completed/*.png"
release:
runs-on: ubuntu-latest
permissions:
contents: write
needs: build
if: always() && contains(needs.*.result, 'success') && !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled')
strategy:
fail-fast: false
matrix:
qbt_libtorrent_version: ["1.2", "2.0"]
include:
- qbt_libtorrent_version: "1.2"
preview_release: true
- qbt_libtorrent_version: "2.0"
preview_release: false
name: "Publish release libtorrent-v${{ matrix.qbt_libtorrent_version }}"
env:
qbt_build_dir: "qbt-build"
steps:
- name: Checkout ${{ github.event.inputs.distinct_id }}
uses: actions/checkout@v4
- name: Pandoc - Bootstrap
run: |
pandoc_git_tag="$(git ls-remote -q -t --refs https://github.com/jgm/pandoc.git | awk '/tags\/[0-9]/{sub("refs/tags/", ""); print $2 }' | awk '!/^$/' | sort -rV | head -n 1)"
curl -sLo- "https://github.com/jgm/pandoc/releases/latest/download/pandoc-${pandoc_git_tag}-linux-amd64.tar.gz" | tar xzf - --strip-components 2 -C "$(pwd)" --exclude="share"
- name: Host - Download 1.2 qbittorrent-nox artifacts ${{ github.event.inputs.distinct_id }}
uses: actions/download-artifact@v4
with:
path: "1.2"
pattern: libtorrent-v1.2-*-qbittorrent-nox
merge-multiple: true
- name: Host - Download 2.0 qbittorrent-nox artifacts ${{ github.event.inputs.distinct_id }}
uses: actions/download-artifact@v4
with:
path: "2.0"
pattern: libtorrent-v2.0-*-qbittorrent-nox
merge-multiple: true
- name: Host - merge release-info ${{ github.event.inputs.distinct_id }}
run: |
if [[ ${{ matrix.qbt_libtorrent_version }} == "1.2" ]]; then
for release in 1\.2/*-release.md; do
[[ -f "${release}" ]] && release+=("${release}")
done
revision="$(jq -r .revision 1\.2/*-dependency-version.json | head -n1)"
fi
if [[ ${{ matrix.qbt_libtorrent_version }} == "2.0" ]]; then
for release in 2\.0/*-release.md; do
[[ -f "${release}" ]] && release+=("${release}")
done
revision="$(jq -r .revision 2\.0/*-dependency-version.json | head -n1)"
fi
readarray -t release_sorted < <(printf '%s\n' "${release[@]}" | sort)
for dependency_version_files in 1\.2/*-dependency-version.json 2\.0/*-dependency-version.json; do
if [[ -f "${dependency_version_files}" ]]; then
sed -r 's/"revision": (.*)/PLACEHOLDER/g' -i "${dependency_version_files}"
dependency_version+=("${dependency_version_files}")
fi
done
readarray -t dependency_version_sorted < <(printf '%s\n' "${dependency_version[@]}" | sort)
paste -d '\n' "${release_sorted[@]}" | uniq | awk '!(NF && seen[$0]++) || /^>/' > "tmp-release.md"
paste -d '\n' "${dependency_version_sorted[@]}" | uniq | awk '!(NF && seen[$0]++)' > "dependency-version.json"
sed -i "s|PLACEHOLDER|\"revision\": \"${revision}\"|" dependency-version.json
./pandoc --wrap=preserve -f gfm tmp-release.md -t gfm -o release.md
- name: Host - Bootstrap release tag ${{ github.event.inputs.distinct_id }}
run: printf '%s\n' "release_tag=$(cat ${{ matrix.qbt_libtorrent_version }}/tag.md)" >> $GITHUB_ENV
- name: Host - Bootstrap release title ${{ github.event.inputs.distinct_id }}
run: printf '%s\n' "release_title=$(cat ${{ matrix.qbt_libtorrent_version }}/title.md)" >> $GITHUB_ENV
- name: Host- Create release - tag - assets ${{ github.event.inputs.distinct_id }}
uses: ncipollo/release-action@v1
with:
prerelease: "${{ matrix.preview_release }}"
artifacts: "${{ matrix.qbt_libtorrent_version }}/*-qbittorrent-nox,dependency-version.json"
replacesArtifacts: true
tag: "${{ env.release_tag }}"
name: "${{ env.release_title }}"
bodyFile: "release.md"
allowUpdates: true
token: "${{ github.TOKEN }}"
rerun-on-failure:
if: failure() && inputs.skip_rerun == '0'
name: rerun-on-failure
needs: release
permissions:
actions: write
runs-on: ubuntu-latest
env:
GH_TOKEN: "${{ github.TOKEN }}"
steps:
- uses: actions/checkout@v4
- name: Trigger rerun workflow on job failures
run: |
inputs_retries="${{ inputs.retries }}"
gh workflow run rerun.yml -f run_id=${{ github.run_id }} -f attempts=${{ github.run_attempt }} -f retries=${inputs_retries:-1}
matrix_multi_build_and_release_artifacts

This workflow uses artifacts to bootstrap the build process. It downloads the dependencies from the workflow repo and uses them to build the binaries. It’s never really used, just a proof of concept.

# @credits https://github.com/c0re100/qBittorrent-Enhanced-Edition
name: matrix multi build and release - artifacts
on:
workflow_dispatch:
inputs:
distinct_id:
description: "Distinct id"
skip_rerun:
description: "Skip rerun?"
required: true
default: true
type: boolean
retries:
description: "Number of rerun retries"
required: true
default: "1"
type: choice
options: ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
permissions:
id-token: write
contents: read
attestations: write
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
bootstrap:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install jq
run: |
sudo apt-get update
sudo apt-get install jq -y
- name: Download Assets
run: |
mapfile -t assets < <(curl -sL "https://api.github.com/repos/userdocs/qbt-workflow-files/releases/latest" | jq -r ".assets | .[].browser_download_url")
for urls in "${assets[@]}"; do
curl -sLO "${urls}"
done
- uses: actions/upload-artifact@v4
with:
path: "*.tar.xz"
build:
needs: bootstrap
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
os_id: [alpine]
os_version_id: [edge]
# qbt_cross_name: [armel,armhf,armv7,aarch64,x86_64,x86,s390x,powerpc,ppc64el,mips,mipsel,mips64,mips64el,riscv64]
qbt_cross_name: ["armhf", "armv7", "aarch64", "x86_64", "x86"]
qbt_libtorrent_version: ["1.2", "2.0"]
qbt_build_tool: ["", "qmake"]
include:
- qbt_build_tool: "qmake"
qbt_qt_version_name: "qt5-"
qbt_qt_version: "5"
- qbt_build_tool: ""
qbt_qt_version_name: ""
qbt_qt_version: "6"
name: "${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}libtorrent-v${{ matrix.qbt_libtorrent_version }}"
env:
qbt_build_dir: "qbt-build"
steps:
- name: Checkout ${{ github.event.inputs.distinct_id }}
uses: actions/checkout@v4
- name: Host - phased updates ${{ github.event.inputs.distinct_id }}
run: printf '%s\n' 'APT::Get::Always-Include-Phased-Updates "false";' | sudo tee /etc/apt/apt.conf.d/99-phased-updates
- name: Host - update ${{ github.event.inputs.distinct_id }}
run: sudo apt-get update
- name: Host - upgrade ${{ github.event.inputs.distinct_id }}
run: sudo apt-get -y upgrade
- name: Host - set up qemu-user-static binfmt-support ${{ github.event.inputs.distinct_id }}
run: sudo apt install libpipeline1 qemu-user-static binfmt-support
- name: Host - create build dir ${{ github.event.inputs.distinct_id }}
run: mkdir -p ${{ env.qbt_build_dir }}
- name: Host - Download all artifacts ${{ github.event.inputs.distinct_id }}
uses: actions/download-artifact@v4
- name: Host - organise libtorrent files ${{ github.event.inputs.distinct_id }}
run: |
libtorrent_1_2_github_tag="$(git ls-remote -q -t --refs "https://github.com/arvidn/libtorrent.git" | awk '/\/v1/{sub("refs/tags/", "");sub("(.*)(-[^0-9].*)(.*)", ""); print $2 }' | awk '!/^$/' | sort -rV | head -n1)"
libtorrent_2_0_github_tag="$(git ls-remote -q -t --refs "https://github.com/arvidn/libtorrent.git" | awk '/\/v2/{sub("refs/tags/", "");sub("(.*)(-[^0-9].*)(.*)", ""); print $2 }' | awk '!/^$/' | sort -rV | head -n1)"
if [[ "${{ matrix.qbt_libtorrent_version }}" =~ ^1\.2 ]]; then
mv -f artifact/libtorrent.${libtorrent_1_2_github_tag/v/}.tar.xz artifact/libtorrent.tar.xz
rm -f artifact/libtorrent.${libtorrent_2_0_github_tag/v/}.tar.xz
fi
if [[ "${{ matrix.qbt_libtorrent_version }}" =~ ^2\.0 ]]; then
mv -f artifact/libtorrent.${libtorrent_2_0_github_tag/v/}.tar.xz artifact/libtorrent.tar.xz
rm -f artifact/libtorrent.${libtorrent_1_2_github_tag/v/}.tar.xz
fi
- name: Host - organise qt files ${{ github.event.inputs.distinct_id }}
run: |
if [[ "${{ matrix.qbt_qt_version }}" =~ ^5 ]]; then
mv -f artifact/qt5base.tar.xz artifact/qtbase.tar.xz
mv -f artifact/qt5tools.tar.xz artifact/qttools.tar.xz
rm -f artifact/qt6base.tar.xz artifact/qt6tools.tar.xz
fi
if [[ "${{ matrix.qbt_qt_version }}" =~ ^6 ]]; then
mv -f artifact/qt6base.tar.xz artifact/qtbase.tar.xz
mv -f artifact/qt6tools.tar.xz artifact/qttools.tar.xz
rm -f artifact/qt5base.tar.xz artifact/qt5tools.tar.xz
fi
- name: Host - Move organised artifacts to ${{ env.qbt_build_dir }} ${{ github.event.inputs.distinct_id }}
run: mv -f artifact/* ${{ env.qbt_build_dir }}
- name: Host - Display structure of downloaded artifacts workspace ${{ github.event.inputs.distinct_id }}
run: ls -R
- name: Host - Create Docker template env file ${{ github.event.inputs.distinct_id }}
run: |
printf '%s\n' "qbt_libtorrent_version=${{ matrix.qbt_libtorrent_version }}" > env.custom
printf '%s\n' "qbt_qt_version=${{ matrix.qbt_qt_version }}" >> env.custom
printf '%s\n' "qbt_build_tool=${{ matrix.qbt_build_tool }}" >> env.custom
printf '%s\n' "qbt_cross_name=${{ matrix.qbt_cross_name }}" >> env.custom
printf '%s\n' "qbt_patches_url=${{ github.repository }}" >> env.custom
printf '%s\n' "qbt_skip_icu=yes" >> env.custom
printf '%s\n' "qbt_boost_tag=" >> env.custom
printf '%s\n' "qbt_libtorrent_tag=" >> env.custom
printf '%s\n' "qbt_qt_tag=" >> env.custom
printf '%s\n' "qbt_qbittorrent_tag=" >> env.custom
printf '%s\n' "qbt_libtorrent_master_jamfile=no" >> env.custom
printf '%s\n' "qbt_workflow_files=no" >> env.custom
printf '%s\n' "qbt_workflow_artifacts=yes" >> env.custom
printf '%s\n' "qbt_cache_dir=" >> env.custom
printf '%s\n' "qbt_optimise_strip=yes" >> env.custom
printf '%s\n' "qbt_build_debug=no" >> env.custom
printf '%s\n' "qbt_revision_url=${{ github.repository }}" >> env.custom
printf '%s\n' "qbt_standard=17" >> env.custom
printf '%s\n' "qbt_static_ish=no" >> env.custom
- name: Host - Create docker multiarch container ${{ github.event.inputs.distinct_id }}
run: docker run --name multiarch -it -d --env-file env.custom -w /root -v ${{ github.workspace }}:/root ${{ matrix.os_id }}:${{ matrix.os_version_id }}
- name: Docker - apk update ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch apk update
- name: Docker - apk install bash ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch apk add bash
- name: Docker - Bootstrap ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh -bs-a
- name: Docker - Copy repo patches to build folder ${{ github.event.inputs.distinct_id }}
run: if [[ -d patches ]]; then docker exec -w /root multiarch cp -r patches/* /root/${{ env.qbt_build_dir }}/patches; fi
- name: Docker - zlib-ng ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh zlib
- name: Docker - iconv ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh iconv
- name: Docker - icu ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh icu
- name: Docker - openssl ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh openssl
- name: Docker - boost ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh boost
- name: Docker - libtorrent ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh libtorrent
- name: Docker - double_conversion ${{ github.event.inputs.distinct_id }}
if: matrix.qbt_build_tool == 'cmake'
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh double_conversion
- name: Docker - qtbase ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh qtbase
- name: Docker - qttools ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh qttools
- name: Docker - qbittorrent ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh qbittorrent
- name: Host - qBittorrent v5 transition
run: |
# When qBittorrent v5 is released, remove this
if [[ -f ${{ env.qbt_build_dir }}/release_info/disable-qt5 ]]; then
printf '%s\n' "disable_qt5=yes" >> $GITHUB_ENV
fi
- name: Docker - Set release asset name ${{ github.event.inputs.distinct_id }}
if: env.disable_qt5 != 'yes' # When qBittorrent v5 is released, remove this
run: docker exec -w /root/${{ env.qbt_build_dir }}/completed multiarch mv -f qbittorrent-nox ${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}qbittorrent-nox
- name: Generate artifact attestation ${{ github.event.inputs.distinct_id }}
if: env.disable_qt5 != 'yes' # When qBittorrent v5 is released, remove this
uses: actions/attest-build-provenance@v1
with:
subject-path: "${{ env.qbt_build_dir }}/completed/${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}qbittorrent-nox"
- name: Docker - Release Info ${{ github.event.inputs.distinct_id }}
if: env.disable_qt5 != 'yes' # When qBittorrent v5 is released, remove this
run: docker exec -w /root/${{ env.qbt_build_dir }}/release_info multiarch bash -c 'mv *.md *.json '/root/${{ env.qbt_build_dir }}/completed''
# - name: Docker - upx compression ${{ github.event.inputs.distinct_id }}
# run: |
# docker exec -w /root multiarch apk add upx
# docker exec -w /root/${{ env.qbt_build_dir }}/completed multiarch upx --brute --no-lzma ${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}qbittorrent-nox
- name: Host - Upload libtorrent-v${{ matrix.qbt_libtorrent_version }}-qbittorrent-nox and release info artifact ${{ github.event.inputs.distinct_id }}
if: env.disable_qt5 != 'yes' # When qBittorrent v5 is released, remove this
uses: actions/upload-artifact@v4
with:
name: libtorrent-v${{ matrix.qbt_libtorrent_version }}-${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}qbittorrent-nox
path: |
${{ env.qbt_build_dir }}/completed/*
!${{ env.qbt_build_dir }}/completed/*.png
- name: Host - Upload cmake graphs artifact ${{ github.event.inputs.distinct_id }}
if: matrix.qbt_build_tool == 'cmake' && env.disable_qt5 != 'yes' # When qBittorrent v5 is released, remove this
uses: actions/upload-artifact@v4
with:
name: "${{ matrix.qbt_cross_name }}-libtorrent-v${{ matrix.qbt_libtorrent_version }}-graphs"
path: "${{ env.qbt_build_dir }}/completed/*.png"
release:
runs-on: ubuntu-latest
permissions:
contents: write
needs: build
if: always() && contains(needs.*.result, 'success') && !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled')
strategy:
fail-fast: false
matrix:
qbt_libtorrent_version: ["1.2", "2.0"]
include:
- qbt_libtorrent_version: "1.2"
preview_release: true
- qbt_libtorrent_version: "2.0"
preview_release: false
name: "Publish release libtorrent-v${{ matrix.qbt_libtorrent_version }}"
env:
qbt_build_dir: "qbt-build"
steps:
- name: Checkout ${{ github.event.inputs.distinct_id }}
uses: actions/checkout@v4
- name: Pandoc - Bootstrap
run: |
pandoc_git_tag="$(git ls-remote -q -t --refs https://github.com/jgm/pandoc.git | awk '/tags\/[0-9]/{sub("refs/tags/", ""); print $2 }' | awk '!/^$/' | sort -rV | head -n 1)"
curl -sLo- "https://github.com/jgm/pandoc/releases/latest/download/pandoc-${pandoc_git_tag}-linux-amd64.tar.gz" | tar xzf - --strip-components 2 -C "$(pwd)" --exclude="share"
- name: Host - Download 1.2 qbittorrent-nox artifacts ${{ github.event.inputs.distinct_id }}
uses: actions/download-artifact@v4
with:
path: "1.2"
pattern: libtorrent-v1.2-*-qbittorrent-nox
merge-multiple: true
- name: Host - Download 2.0 qbittorrent-nox artifacts ${{ github.event.inputs.distinct_id }}
uses: actions/download-artifact@v4
with:
path: "2.0"
pattern: libtorrent-v2.0-*-qbittorrent-nox
merge-multiple: true
- name: Host - merge release-info ${{ github.event.inputs.distinct_id }}
run: |
if [[ ${{ matrix.qbt_libtorrent_version }} == "1.2" ]]; then
for release in 1\.2/*-release.md; do
[[ -f "${release}" ]] && release+=("${release}")
done
revision="$(jq -r .revision 1\.2/*-dependency-version.json | head -n1)"
fi
if [[ ${{ matrix.qbt_libtorrent_version }} == "2.0" ]]; then
for release in 2\.0/*-release.md; do
[[ -f "${release}" ]] && release+=("${release}")
done
revision="$(jq -r .revision 2\.0/*-dependency-version.json | head -n1)"
fi
readarray -t release_sorted < <(printf '%s\n' "${release[@]}" | sort)
for dependency_version_files in 1\.2/*-dependency-version.json 2\.0/*-dependency-version.json; do
if [[ -f "${dependency_version_files}" ]]; then
sed -r 's/"revision": (.*)/PLACEHOLDER/g' -i "${dependency_version_files}"
dependency_version+=("${dependency_version_files}")
fi
done
readarray -t dependency_version_sorted < <(printf '%s\n' "${dependency_version[@]}" | sort)
paste -d '\n' "${release_sorted[@]}" | uniq | awk '!(NF && seen[$0]++) || /^>/' > "tmp-release.md"
paste -d '\n' "${dependency_version_sorted[@]}" | uniq | awk '!(NF && seen[$0]++)' > "dependency-version.json"
sed -i "s|PLACEHOLDER|\"revision\": \"${revision}\"|" dependency-version.json
./pandoc --wrap=preserve -f gfm tmp-release.md -t gfm -o release.md
- name: Host - Bootstrap release tag ${{ github.event.inputs.distinct_id }}
run: printf '%s\n' "release_tag=$(cat ${{ matrix.qbt_libtorrent_version }}/tag.md)" >> $GITHUB_ENV
- name: Host - Bootstrap release title ${{ github.event.inputs.distinct_id }}
run: printf '%s\n' "release_title=$(cat ${{ matrix.qbt_libtorrent_version }}/title.md)" >> $GITHUB_ENV
- name: Host- Create release - tag - assets ${{ github.event.inputs.distinct_id }}
uses: ncipollo/release-action@v1
with:
prerelease: "${{ matrix.preview_release }}"
artifacts: "${{ matrix.qbt_libtorrent_version }}/*-qbittorrent-nox,dependency-version.json"
replacesArtifacts: true
tag: "${{ env.release_tag }}"
name: "${{ env.release_title }}"
bodyFile: "release.md"
allowUpdates: true
token: "${{ github.TOKEN }}"
rerun-on-failure:
if: failure() && inputs.skip_rerun == '0'
name: rerun-on-failure
needs: release
permissions:
actions: write
runs-on: ubuntu-latest
env:
GH_TOKEN: "${{ github.TOKEN }}"
steps:
- uses: actions/checkout@v4
- name: Trigger rerun workflow on job failures
run: |
inputs_retries="${{ inputs.retries }}"
gh workflow run rerun.yml -f run_id=${{ github.run_id }} -f attempts=${{ github.run_attempt }} -f retries=${inputs_retries:-1}
matrix_multi_build_and_release_customs_tags

This workflow runs the script in the artifact configuration, downloading dependencies from the workflow latest releases to bootstrap as artifacts the matrix will use.

# @credits https://github.com/c0re100/qBittorrent-Enhanced-Edition
name: matrix multi build and release - customs tags
on:
workflow_dispatch:
inputs:
distinct_id:
description: "Distinct id"
skip_rerun:
description: "Skip rerun?"
required: true
default: true
type: boolean
retries:
description: "Number of rerun retries"
required: true
default: "1"
type: choice
options: ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
permissions:
id-token: write
contents: read
attestations: write
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
os_id: [alpine]
os_version_id: [edge]
# qbt_cross_name: [armel,armhf,armv7,aarch64,x86_64,x86,s390x,powerpc,ppc64el,mips,mipsel,mips64,mips64el,riscv64]
qbt_cross_name: ["armhf", "armv7", "aarch64", "x86_64", "x86"]
qbt_libtorrent_version: ["1.2", "2.0"]
qbt_build_tool: ["", "qmake"]
# qbt_boost_tag: [boost-1.84.0]
# qbt_qbittorrent_tag: [master]
include:
- qbt_build_tool: "qmake"
qbt_qt_version_name: "qt5-"
qbt_qt_version: "5"
# qbt_qt_tag: "v5.15.11-lts-lgpl"
- qbt_build_tool: ""
qbt_qt_version_name: ""
qbt_qt_version: "6"
qbt_qt_tag: "v6.7.0-beta3"
- qbt_libtorrent_version: "2.0"
qbt_libtorrent_tag: "RC_2_0"
- qbt_libtorrent_version: "1.2"
qbt_libtorrent_tag: "RC_1_2"
name: "${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}libtorrent-v${{ matrix.qbt_libtorrent_version }}"
env:
qbt_build_dir: "qbt-build"
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Host - phased updates
run: printf '%s\n' 'APT::Get::Always-Include-Phased-Updates "false";' | sudo tee /etc/apt/apt.conf.d/99-phased-updates
- name: Host - update
run: sudo apt-get update
- name: Host - upgrade
run: sudo apt-get -y upgrade
- name: Host - set up qemu-user-static binfmt-support
run: sudo apt install libpipeline1 qemu-user-static binfmt-support
- name: Host - Create Docker template env file
run: |
printf '%s\n' "qbt_libtorrent_version=${{ matrix.qbt_libtorrent_version }}" > env.custom
printf '%s\n' "qbt_qt_version=${{ matrix.qbt_qt_version }}" >> env.custom
printf '%s\n' "qbt_build_tool=${{ matrix.qbt_build_tool }}" >> env.custom
printf '%s\n' "qbt_cross_name=${{ matrix.qbt_cross_name }}" >> env.custom
printf '%s\n' "qbt_patches_url=${{ github.repository }}" >> env.custom
printf '%s\n' "qbt_skip_icu=yes" >> env.custom
printf '%s\n' "qbt_boost_tag=${{ matrix.qbt_boost_tag }}" >> env.custom
printf '%s\n' "qbt_libtorrent_tag=${{ matrix.qbt_libtorrent_tag }}" >> env.custom
printf '%s\n' "qbt_qt_tag=${{ matrix.qbt_qt_tag }}" >> env.custom
printf '%s\n' "qbt_qbittorrent_tag=${{ matrix.qbt_qbittorrent_tag }}" >> env.custom
printf '%s\n' "qbt_libtorrent_master_jamfile=no" >> env.custom
printf '%s\n' "qbt_workflow_files=yes" >> env.custom
printf '%s\n' "qbt_workflow_artifacts=no" >> env.custom
printf '%s\n' "qbt_cache_dir=" >> env.custom
printf '%s\n' "qbt_optimise_strip=yes" >> env.custom
printf '%s\n' "qbt_build_debug=no" >> env.custom
printf '%s\n' "qbt_revision_url=${{ github.repository }}" >> env.custom
printf '%s\n' "qbt_standard=17" >> env.custom
printf '%s\n' "qbt_static_ish=no" >> env.custom
- name: Host - Create docker multiarch container
run: docker run --name multiarch -it -d --env-file env.custom -w /root -v ${{ github.workspace }}:/root ${{ matrix.os_id }}:${{ matrix.os_version_id }}
- name: Docker - apk update
run: docker exec -w /root multiarch apk update
- name: Docker - apk install bash
run: docker exec -w /root multiarch apk add bash
- name: Docker - Bootstrap
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh -bs-a
- name: Docker - Copy repo patches to build folder
run: if [[ -d patches ]]; then docker exec -w /root multiarch cp -r patches/* /root/${{ env.qbt_build_dir }}/patches; fi
- name: Docker - zlib-ng
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh zlib
- name: Docker - iconv
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh iconv
- name: Docker - icu
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh icu
- name: Docker - openssl
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh openssl
- name: Docker - boost
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh boost
- name: Docker - libtorrent
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh libtorrent
- name: Docker - double_conversion
if: matrix.qbt_build_tool == 'cmake'
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh double_conversion
- name: Docker - qtbase
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh qtbase
- name: Docker - qttools
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh qttools
- name: Docker - qbittorrent
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh qbittorrent
- name: Host - qBittorrent v5 transition
run: |
# When qBittorrent v5 is released, remove this
if [[ -f ${{ env.qbt_build_dir }}/release_info/disable-qt5 ]]; then
printf '%s\n' "disable_qt5=yes" >> $GITHUB_ENV
fi
- name: Docker - Set release asset name
if: env.disable_qt5 != 'yes' # When qBittorrent v5 is released, remove this
run: docker exec -w /root/${{ env.qbt_build_dir }}/completed multiarch mv -f qbittorrent-nox ${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}qbittorrent-nox
- name: Generate artifact attestation
if: env.disable_qt5 != 'yes' # When qBittorrent v5 is released, remove this
uses: actions/attest-build-provenance@v1
with:
subject-path: "${{ env.qbt_build_dir }}/completed/${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}qbittorrent-nox"
- name: Docker - Release Info
if: env.disable_qt5 != 'yes' # When qBittorrent v5 is released, remove this
run: docker exec -w /root/${{ env.qbt_build_dir }}/release_info multiarch bash -c 'mv *.md *.json '/root/${{ env.qbt_build_dir }}/completed''
# - name: Docker - upx compression
# run: |
# docker exec -w /root multiarch apk add upx
# docker exec -w /root/${{ env.qbt_build_dir }}/completed multiarch upx --brute --no-lzma ${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}qbittorrent-nox
- name: Host - Upload libtorrent-v${{ matrix.qbt_libtorrent_version }}-qbittorrent-nox and release info artifact
if: env.disable_qt5 != 'yes' # When qBittorrent v5 is released, remove this
uses: actions/upload-artifact@v4
with:
name: libtorrent-v${{ matrix.qbt_libtorrent_version }}-${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}qbittorrent-nox
path: |
${{ env.qbt_build_dir }}/completed/*
!${{ env.qbt_build_dir }}/completed/*.png
- name: Host - Upload cmake graphs artifact
if: matrix.qbt_build_tool == 'cmake' && env.disable_qt5 != 'yes' # When qBittorrent v5 is released, remove this
uses: actions/upload-artifact@v4
with:
name: "${{ matrix.qbt_cross_name }}-libtorrent-v${{ matrix.qbt_libtorrent_version }}-graphs"
path: "${{ env.qbt_build_dir }}/completed/*.png"
release:
runs-on: ubuntu-latest
permissions:
contents: write
needs: build
if: always() && contains(needs.*.result, 'success') && !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled')
strategy:
fail-fast: false
matrix:
qbt_libtorrent_version: ["1.2", "2.0"]
include:
- qbt_libtorrent_version: "1.2"
preview_release: true
- qbt_libtorrent_version: "2.0"
preview_release: false
name: "Publish release libtorrent-v${{ matrix.qbt_libtorrent_version }}"
env:
qbt_build_dir: "qbt-build"
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Pandoc - Bootstrap
run: |
pandoc_git_tag="$(git ls-remote -q -t --refs https://github.com/jgm/pandoc.git | awk '/tags\/[0-9]/{sub("refs/tags/", ""); print $2 }' | awk '!/^$/' | sort -rV | head -n 1)"
curl -sLo- "https://github.com/jgm/pandoc/releases/latest/download/pandoc-${pandoc_git_tag}-linux-amd64.tar.gz" | tar xzf - --strip-components 2 -C "$(pwd)" --exclude="share"
- name: Host - Download 1.2 qbittorrent-nox artifacts
uses: actions/download-artifact@v4
with:
path: "1.2"
pattern: libtorrent-v1.2-*-qbittorrent-nox
merge-multiple: true
- name: Host - Download 2.0 qbittorrent-nox artifacts
uses: actions/download-artifact@v4
with:
path: "2.0"
pattern: libtorrent-v2.0-*-qbittorrent-nox
merge-multiple: true
- name: Host - merge release-info
run: |
if [[ ${{ matrix.qbt_libtorrent_version }} == "1.2" ]]; then
for release in 1\.2/*-release.md; do
[[ -f "${release}" ]] && release+=("${release}")
done
revision="$(jq -r .revision 1\.2/*-dependency-version.json | head -n1)"
fi
if [[ ${{ matrix.qbt_libtorrent_version }} == "2.0" ]]; then
for release in 2\.0/*-release.md; do
[[ -f "${release}" ]] && release+=("${release}")
done
revision="$(jq -r .revision 2\.0/*-dependency-version.json | head -n1)"
fi
readarray -t release_sorted < <(printf '%s\n' "${release[@]}" | sort)
for dependency_version_files in 1\.2/*-dependency-version.json 2\.0/*-dependency-version.json; do
if [[ -f "${dependency_version_files}" ]]; then
sed -r 's/"revision": (.*)/PLACEHOLDER/g' -i "${dependency_version_files}"
dependency_version+=("${dependency_version_files}")
fi
done
readarray -t dependency_version_sorted < <(printf '%s\n' "${dependency_version[@]}" | sort)
paste -d '\n' "${release_sorted[@]}" | uniq | awk '!(NF && seen[$0]++) || /^>/' > "tmp-release.md"
paste -d '\n' "${dependency_version_sorted[@]}" | uniq | awk '!(NF && seen[$0]++)' > "dependency-version.json"
sed -i "s|PLACEHOLDER|\"revision\": \"${revision}\"|" dependency-version.json
./pandoc --wrap=preserve -f gfm tmp-release.md -t gfm -o release.md
- name: Host - Bootstrap release tag
run: printf '%s\n' "release_tag=$(cat ${{ matrix.qbt_libtorrent_version }}/tag.md)" >> $GITHUB_ENV
- name: Host - Bootstrap release title
run: printf '%s\n' "release_title=$(cat ${{ matrix.qbt_libtorrent_version }}/title.md)" >> $GITHUB_ENV
- name: Host- Create release - tag - assets
uses: ncipollo/release-action@v1
with:
prerelease: "${{ matrix.preview_release }}"
artifacts: "${{ matrix.qbt_libtorrent_version }}/*-qbittorrent-nox,dependency-version.json"
replacesArtifacts: true
tag: "${{ env.release_tag }}"
name: "${{ env.release_title }}"
bodyFile: "release.md"
allowUpdates: true
token: "${{ github.TOKEN }}"
rerun-on-failure:
if: failure() && inputs.skip_rerun == '0'
name: rerun-on-failure
needs: release
permissions:
actions: write
runs-on: ubuntu-latest
env:
GH_TOKEN: "${{ github.TOKEN }}"
steps:
- uses: actions/checkout@v4
- name: Trigger rerun workflow on job failures
run: |
inputs_retries="${{ inputs.retries }}"
gh workflow run rerun.yml -f run_id=${{ github.run_id }} -f attempts=${{ github.run_attempt }} -f retries=${inputs_retries:-1}
matrix_multi_build_and_release_qbt_workflow_files

This workflow runs the script in the workflow configuration, downloading dependencies from the workflow latest releases.

# @credits https://github.com/c0re100/qBittorrent-Enhanced-Edition
name: matrix multi build and release - qbt-workflow-files
on:
workflow_dispatch:
inputs:
distinct_id:
description: "Distinct id"
skip_rerun:
description: "Skip rerun?"
required: true
default: true
type: boolean
retries:
description: "Number of rerun retries"
required: true
default: "1"
type: choice
options: ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
permissions:
id-token: write
contents: read
attestations: write
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
os_id: [alpine]
os_version_id: [edge]
# qbt_cross_name: [armel,armhf,armv7,aarch64,x86_64,x86,s390x,powerpc,ppc64el,mips,mipsel,mips64,mips64el,riscv64]
qbt_cross_name: ["armhf", "armv7", "aarch64", "x86_64", "x86"]
qbt_libtorrent_version: ["1.2", "2.0"]
qbt_build_tool: ["", "qmake"]
include:
- qbt_build_tool: "qmake"
qbt_qt_version_name: "qt5-"
qbt_qt_version: "5"
- qbt_build_tool: ""
qbt_qt_version_name: ""
qbt_qt_version: "6"
name: "${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}libtorrent-v${{ matrix.qbt_libtorrent_version }}"
env:
qbt_build_dir: "qbt-build"
steps:
- name: Checkout ${{ github.event.inputs.distinct_id }}
uses: actions/checkout@v4
- name: Host - phased updates ${{ github.event.inputs.distinct_id }}
run: printf '%s\n' 'APT::Get::Always-Include-Phased-Updates "false";' | sudo tee /etc/apt/apt.conf.d/99-phased-updates
- name: Host - update ${{ github.event.inputs.distinct_id }}
run: sudo apt-get update
- name: Host - upgrade ${{ github.event.inputs.distinct_id }}
run: sudo apt-get -y upgrade
- name: Host - set up qemu-user-static binfmt-support ${{ github.event.inputs.distinct_id }}
run: sudo apt install libpipeline1 qemu-user-static binfmt-support
- name: Host - Create Docker template env file ${{ github.event.inputs.distinct_id }}
run: |
printf '%s\n' "qbt_libtorrent_version=${{ matrix.qbt_libtorrent_version }}" > env.custom
printf '%s\n' "qbt_qt_version=${{ matrix.qbt_qt_version }}" >> env.custom
printf '%s\n' "qbt_build_tool=${{ matrix.qbt_build_tool }}" >> env.custom
printf '%s\n' "qbt_cross_name=${{ matrix.qbt_cross_name }}" >> env.custom
printf '%s\n' "qbt_patches_url=${{ github.repository }}" >> env.custom
printf '%s\n' "qbt_skip_icu=yes" >> env.custom
printf '%s\n' "qbt_boost_tag=" >> env.custom
printf '%s\n' "qbt_libtorrent_tag=" >> env.custom
printf '%s\n' "qbt_qt_tag=" >> env.custom
printf '%s\n' "qbt_qbittorrent_tag=" >> env.custom
printf '%s\n' "qbt_libtorrent_master_jamfile=no" >> env.custom
printf '%s\n' "qbt_workflow_files=yes" >> env.custom
printf '%s\n' "qbt_workflow_artifacts=no" >> env.custom
printf '%s\n' "qbt_cache_dir=" >> env.custom
printf '%s\n' "qbt_optimise_strip=yes" >> env.custom
printf '%s\n' "qbt_build_debug=no" >> env.custom
printf '%s\n' "qbt_revision_url=${{ github.repository }}" >> env.custom
printf '%s\n' "qbt_standard=17" >> env.custom
printf '%s\n' "qbt_static_ish=no" >> env.custom
- name: Host - Create docker multiarch container ${{ github.event.inputs.distinct_id }}
run: docker run --name multiarch -it -d --env-file env.custom -w /root -v ${{ github.workspace }}:/root ${{ matrix.os_id }}:${{ matrix.os_version_id }}
- name: Docker - apk update ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch apk update
- name: Docker - apk install bash ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch apk add bash
- name: Docker - Bootstrap ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh -bs-a
- name: Docker - Copy repo patches to build folder ${{ github.event.inputs.distinct_id }}
run: if [[ -d patches ]]; then docker exec -w /root multiarch cp -r patches/* /root/${{ env.qbt_build_dir }}/patches; fi
- name: Docker - zlib-ng ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh zlib
- name: Docker - iconv ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh iconv
- name: Docker - icu ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh icu
- name: Docker - openssl ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh openssl
- name: Docker - boost ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh boost
- name: Docker - libtorrent ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh libtorrent
- name: Docker - double_conversion ${{ github.event.inputs.distinct_id }}
if: matrix.qbt_build_tool == 'cmake'
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh double_conversion
- name: Docker - qtbase ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh qtbase
- name: Docker - qttools ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh qttools
- name: Docker - qbittorrent ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh qbittorrent
- name: Host - qBittorrent v5 transition
run: |
# When qBittorrent v5 is released, remove this
if [[ -f ${{ env.qbt_build_dir }}/release_info/disable-qt5 ]]; then
printf '%s\n' "disable_qt5=yes" >> $GITHUB_ENV
fi
- name: Docker - Set release asset name ${{ github.event.inputs.distinct_id }}
if: env.disable_qt5 != 'yes' # When qBittorrent v5 is released, remove this
run: docker exec -w /root/${{ env.qbt_build_dir }}/completed multiarch mv -f qbittorrent-nox ${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}qbittorrent-nox
- name: Generate artifact attestation ${{ github.event.inputs.distinct_id }}
if: env.disable_qt5 != 'yes' # When qBittorrent v5 is released, remove this
uses: actions/attest-build-provenance@v1
with:
subject-path: "${{ env.qbt_build_dir }}/completed/${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}qbittorrent-nox"
- name: Docker - Release Info ${{ github.event.inputs.distinct_id }}
if: env.disable_qt5 != 'yes' # When qBittorrent v5 is released, remove this
run: docker exec -w /root/${{ env.qbt_build_dir }}/release_info multiarch bash -c 'mv *.md *.json '/root/${{ env.qbt_build_dir }}/completed''
# - name: Docker - upx compression ${{ github.event.inputs.distinct_id }}
# run: |
# docker exec -w /root multiarch apk add upx
# docker exec -w /root/${{ env.qbt_build_dir }}/completed multiarch upx --brute --no-lzma ${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}qbittorrent-nox
- name: Host - Upload libtorrent-v${{ matrix.qbt_libtorrent_version }}-qbittorrent-nox and release info artifact ${{ github.event.inputs.distinct_id }}
if: env.disable_qt5 != 'yes' # When qBittorrent v5 is released, remove this
uses: actions/upload-artifact@v4
with:
name: libtorrent-v${{ matrix.qbt_libtorrent_version }}-${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}qbittorrent-nox
path: |
${{ env.qbt_build_dir }}/completed/*
!${{ env.qbt_build_dir }}/completed/*.png
- name: Host - Upload cmake graphs artifact ${{ github.event.inputs.distinct_id }}
if: matrix.qbt_build_tool == 'cmake' && env.disable_qt5 != 'yes' # When qBittorrent v5 is released, remove this
uses: actions/upload-artifact@v4
with:
name: "${{ matrix.qbt_cross_name }}-libtorrent-v${{ matrix.qbt_libtorrent_version }}-graphs"
path: "${{ env.qbt_build_dir }}/completed/*.png"
release:
runs-on: ubuntu-latest
permissions:
contents: write
needs: build
if: always() && contains(needs.*.result, 'success') && !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled')
strategy:
fail-fast: false
matrix:
qbt_libtorrent_version: ["1.2", "2.0"]
include:
- qbt_libtorrent_version: "1.2"
preview_release: true
- qbt_libtorrent_version: "2.0"
preview_release: false
name: "Publish release libtorrent-v${{ matrix.qbt_libtorrent_version }}"
env:
qbt_build_dir: "qbt-build"
steps:
- name: Checkout ${{ github.event.inputs.distinct_id }}
uses: actions/checkout@v4
- name: Pandoc - Bootstrap
run: |
pandoc_git_tag="$(git ls-remote -q -t --refs https://github.com/jgm/pandoc.git | awk '/tags\/[0-9]/{sub("refs/tags/", ""); print $2 }' | awk '!/^$/' | sort -rV | head -n 1)"
curl -sLo- "https://github.com/jgm/pandoc/releases/latest/download/pandoc-${pandoc_git_tag}-linux-amd64.tar.gz" | tar xzf - --strip-components 2 -C "$(pwd)" --exclude="share"
- name: Host - Download 1.2 qbittorrent-nox artifacts ${{ github.event.inputs.distinct_id }}
uses: actions/download-artifact@v4
with:
path: "1.2"
pattern: libtorrent-v1.2-*-qbittorrent-nox
merge-multiple: true
- name: Host - Download 2.0 qbittorrent-nox artifacts ${{ github.event.inputs.distinct_id }}
uses: actions/download-artifact@v4
with:
path: "2.0"
pattern: libtorrent-v2.0-*-qbittorrent-nox
merge-multiple: true
- name: Host - merge release-info ${{ github.event.inputs.distinct_id }}
run: |
if [[ ${{ matrix.qbt_libtorrent_version }} == "1.2" ]]; then
for release in 1\.2/*-release.md; do
[[ -f "${release}" ]] && release+=("${release}")
done
revision="$(jq -r .revision 1\.2/*-dependency-version.json | head -n1)"
fi
if [[ ${{ matrix.qbt_libtorrent_version }} == "2.0" ]]; then
for release in 2\.0/*-release.md; do
[[ -f "${release}" ]] && release+=("${release}")
done
revision="$(jq -r .revision 2\.0/*-dependency-version.json | head -n1)"
fi
readarray -t release_sorted < <(printf '%s\n' "${release[@]}" | sort)
for dependency_version_files in 1\.2/*-dependency-version.json 2\.0/*-dependency-version.json; do
if [[ -f "${dependency_version_files}" ]]; then
sed -r 's/"revision": (.*)/PLACEHOLDER/g' -i "${dependency_version_files}"
dependency_version+=("${dependency_version_files}")
fi
done
readarray -t dependency_version_sorted < <(printf '%s\n' "${dependency_version[@]}" | sort)
paste -d '\n' "${release_sorted[@]}" | uniq | awk '!(NF && seen[$0]++) || /^>/' > "tmp-release.md"
paste -d '\n' "${dependency_version_sorted[@]}" | uniq | awk '!(NF && seen[$0]++)' > "dependency-version.json"
sed -i "s|PLACEHOLDER|\"revision\": \"${revision}\"|" dependency-version.json
./pandoc --wrap=preserve -f gfm tmp-release.md -t gfm -o release.md
- name: Host - Bootstrap release tag ${{ github.event.inputs.distinct_id }}
run: printf '%s\n' "release_tag=$(cat ${{ matrix.qbt_libtorrent_version }}/tag.md)" >> $GITHUB_ENV
- name: Host - Bootstrap release title ${{ github.event.inputs.distinct_id }}
run: printf '%s\n' "release_title=$(cat ${{ matrix.qbt_libtorrent_version }}/title.md)" >> $GITHUB_ENV
- name: Host- Create release - tag - assets ${{ github.event.inputs.distinct_id }}
uses: ncipollo/release-action@v1
with:
prerelease: "${{ matrix.preview_release }}"
artifacts: "${{ matrix.qbt_libtorrent_version }}/*-qbittorrent-nox,dependency-version.json"
replacesArtifacts: true
tag: "${{ env.release_tag }}"
name: "${{ env.release_title }}"
bodyFile: "release.md"
allowUpdates: true
token: "${{ github.TOKEN }}"
rerun-on-failure:
if: failure() && inputs.skip_rerun == '0'
name: rerun-on-failure
needs: release
permissions:
actions: write
runs-on: ubuntu-latest
env:
GH_TOKEN: "${{ github.TOKEN }}"
steps:
- uses: actions/checkout@v4
- name: Trigger rerun workflow on job failures
run: |
inputs_retries="${{ inputs.retries }}"
gh workflow run rerun.yml -f run_id=${{ github.run_id }} -f attempts=${{ github.run_attempt }} -f retries=${inputs_retries:-1}
matrix_multi_build_and_release_qbt_workflow_files_debug

This workflow runs the script in the workflow configuration activate the debug builds.

# @credits https://github.com/c0re100/qBittorrent-Enhanced-Edition
name: matrix multi build and release debug - qbt-workflow-files
on:
workflow_dispatch:
inputs:
distinct_id:
description: "Distinct id"
skip_rerun:
description: "Skip rerun?"
required: true
default: true
type: boolean
retries:
description: "Number of rerun retries"
required: true
default: "1"
type: choice
options: ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
permissions:
id-token: write
contents: read
attestations: write
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
os_id: [alpine]
os_version_id: [edge]
# qbt_cross_name: [armel,armhf,armv7,aarch64,x86_64,x86,s390x,powerpc,ppc64el,mips,mipsel,mips64,mips64el,riscv64]
qbt_cross_name: ["armhf", "armv7", "aarch64", "x86_64", "x86"]
qbt_libtorrent_version: ["1.2", "2.0"]
qbt_build_tool: ["", "qmake"]
include:
- qbt_build_tool: "qmake"
qbt_qt_version_name: "qt5-"
qbt_qt_version: "5"
- qbt_build_tool: ""
qbt_qt_version_name: ""
qbt_qt_version: "6"
name: "${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}libtorrent-v${{ matrix.qbt_libtorrent_version }}"
env:
qbt_build_dir: "qbt-build"
steps:
- name: Checkout ${{ github.event.inputs.distinct_id }}
uses: actions/checkout@v4
- name: Host - phased updates ${{ github.event.inputs.distinct_id }}
run: printf '%s\n' 'APT::Get::Always-Include-Phased-Updates "false";' | sudo tee /etc/apt/apt.conf.d/99-phased-updates
- name: Host - update ${{ github.event.inputs.distinct_id }}
run: sudo apt-get update
- name: Host - upgrade ${{ github.event.inputs.distinct_id }}
run: sudo apt-get -y upgrade
- name: Host - set up qemu-user-static binfmt-support ${{ github.event.inputs.distinct_id }}
run: sudo apt install libpipeline1 qemu-user-static binfmt-support
- name: Host - Create Docker template env file ${{ github.event.inputs.distinct_id }}
run: |
printf '%s\n' "qbt_libtorrent_version=${{ matrix.qbt_libtorrent_version }}" > env.custom
printf '%s\n' "qbt_qt_version=${{ matrix.qbt_qt_version }}" >> env.custom
printf '%s\n' "qbt_build_tool=${{ matrix.qbt_build_tool }}" >> env.custom
printf '%s\n' "qbt_cross_name=${{ matrix.qbt_cross_name }}" >> env.custom
printf '%s\n' "qbt_patches_url=${{ github.repository }}" >> env.custom
printf '%s\n' "qbt_skip_icu=yes" >> env.custom
printf '%s\n' "qbt_boost_tag=" >> env.custom
printf '%s\n' "qbt_libtorrent_tag=" >> env.custom
printf '%s\n' "qbt_qt_tag=" >> env.custom
printf '%s\n' "qbt_qbittorrent_tag=" >> env.custom
printf '%s\n' "qbt_libtorrent_master_jamfile=no" >> env.custom
printf '%s\n' "qbt_workflow_files=yes" >> env.custom
printf '%s\n' "qbt_workflow_artifacts=no" >> env.custom
printf '%s\n' "qbt_cache_dir=" >> env.custom
printf '%s\n' "qbt_optimise_strip=no" >> env.custom
printf '%s\n' "qbt_build_debug=yes" >> env.custom
printf '%s\n' "qbt_revision_url=${{ github.repository }}" >> env.custom
printf '%s\n' "qbt_standard=17" >> env.custom
printf '%s\n' "qbt_static_ish=no" >> env.custom
- name: Host - Create docker multiarch container ${{ github.event.inputs.distinct_id }}
run: docker run --name multiarch -it -d --env-file env.custom -w /root -v ${{ github.workspace }}:/root ${{ matrix.os_id }}:${{ matrix.os_version_id }}
- name: Docker - apk update ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch apk update
- name: Docker - apk install bash ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch apk add bash
- name: Docker - Bootstrap ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh -bs-a
- name: Docker - Copy repo patches to build folder ${{ github.event.inputs.distinct_id }}
run: if [[ -d patches ]]; then docker exec -w /root multiarch cp -r patches/* /root/${{ env.qbt_build_dir }}/patches; fi
- name: Docker - zlib-ng ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh zlib
- name: Docker - iconv ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh iconv
- name: Docker - icu ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh icu
- name: Docker - openssl ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh openssl
- name: Docker - boost ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh boost
- name: Docker - libtorrent ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh libtorrent
- name: Docker - double_conversion ${{ github.event.inputs.distinct_id }}
if: matrix.qbt_build_tool == 'cmake'
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh double_conversion
- name: Docker - qtbase ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh qtbase
- name: Docker - qttools ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh qttools
- name: Docker - qbittorrent ${{ github.event.inputs.distinct_id }}
run: docker exec -w /root multiarch bash qbittorrent-nox-static.sh qbittorrent
- name: Host - qBittorrent v5 transition
run: |
# When qBittorrent v5 is released, remove this
if [[ -f ${{ env.qbt_build_dir }}/release_info/disable-qt5 ]]; then
printf '%s\n' "disable_qt5=yes" >> $GITHUB_ENV
fi
- name: Docker - Set release asset name ${{ github.event.inputs.distinct_id }}
if: env.disable_qt5 != 'yes' # When qBittorrent v5 is released, remove this
run: docker exec -w /root/${{ env.qbt_build_dir }}/completed multiarch mv -f qbittorrent-nox ${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}qbittorrent-nox
- name: Generate artifact attestation ${{ github.event.inputs.distinct_id }}
if: env.disable_qt5 != 'yes' # When qBittorrent v5 is released, remove this
uses: actions/attest-build-provenance@v1
with:
subject-path: "${{ env.qbt_build_dir }}/completed/${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}qbittorrent-nox"
- name: Docker - Release Info ${{ github.event.inputs.distinct_id }}
if: env.disable_qt5 != 'yes' # When qBittorrent v5 is released, remove this
run: docker exec -w /root/${{ env.qbt_build_dir }}/release_info multiarch bash -c 'mv *.md *.json '/root/${{ env.qbt_build_dir }}/completed''
# - name: Docker - upx compression ${{ github.event.inputs.distinct_id }}
# run: |
# docker exec -w /root multiarch apk add upx
# docker exec -w /root/${{ env.qbt_build_dir }}/completed multiarch upx --brute --no-lzma ${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}qbittorrent-nox
- name: Host - Upload libtorrent-v${{ matrix.qbt_libtorrent_version }}-qbittorrent-nox and release info artifact ${{ github.event.inputs.distinct_id }}
if: env.disable_qt5 != 'yes' # When qBittorrent v5 is released, remove this
uses: actions/upload-artifact@v4
with:
name: libtorrent-v${{ matrix.qbt_libtorrent_version }}-${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}qbittorrent-nox
path: |
${{ env.qbt_build_dir }}/completed/*
!${{ env.qbt_build_dir }}/completed/*.png
- name: Host - Upload cmake graphs artifact ${{ github.event.inputs.distinct_id }}
if: matrix.qbt_build_tool == 'cmake' && env.disable_qt5 != 'yes' # When qBittorrent v5 is released, remove this
uses: actions/upload-artifact@v4
with:
name: "${{ matrix.qbt_cross_name }}-libtorrent-v${{ matrix.qbt_libtorrent_version }}-graphs"
path: "${{ env.qbt_build_dir }}/completed/*.png"
release:
runs-on: ubuntu-latest
permissions:
contents: write
needs: build
if: always() && contains(needs.*.result, 'success') && !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled')
strategy:
fail-fast: false
matrix:
qbt_libtorrent_version: ["1.2", "2.0"]
include:
- qbt_libtorrent_version: "1.2"
preview_release: true
- qbt_libtorrent_version: "2.0"
preview_release: false
name: "Publish release libtorrent-v${{ matrix.qbt_libtorrent_version }}"
env:
qbt_build_dir: "qbt-build"
steps:
- name: Checkout ${{ github.event.inputs.distinct_id }}
uses: actions/checkout@v4
- name: Pandoc - Bootstrap
run: |
pandoc_git_tag="$(git ls-remote -q -t --refs https://github.com/jgm/pandoc.git | awk '/tags\/[0-9]/{sub("refs/tags/", ""); print $2 }' | awk '!/^$/' | sort -rV | head -n 1)"
curl -sLo- "https://github.com/jgm/pandoc/releases/latest/download/pandoc-${pandoc_git_tag}-linux-amd64.tar.gz" | tar xzf - --strip-components 2 -C "$(pwd)" --exclude="share"
- name: Host - Download 1.2 qbittorrent-nox artifacts ${{ github.event.inputs.distinct_id }}
uses: actions/download-artifact@v4
with:
path: "1.2"
pattern: libtorrent-v1.2-*-qbittorrent-nox
merge-multiple: true
- name: Host - Download 2.0 qbittorrent-nox artifacts ${{ github.event.inputs.distinct_id }}
uses: actions/download-artifact@v4
with:
path: "2.0"
pattern: libtorrent-v2.0-*-qbittorrent-nox
merge-multiple: true
- name: Host - merge release-info ${{ github.event.inputs.distinct_id }}
run: |
if [[ ${{ matrix.qbt_libtorrent_version }} == "1.2" ]]; then
for release in 1\.2/*-release.md; do
[[ -f "${release}" ]] && release+=("${release}")
done
revision="$(jq -r .revision 1\.2/*-dependency-version.json | head -n1)"
fi
if [[ ${{ matrix.qbt_libtorrent_version }} == "2.0" ]]; then
for release in 2\.0/*-release.md; do
[[ -f "${release}" ]] && release+=("${release}")
done
revision="$(jq -r .revision 2\.0/*-dependency-version.json | head -n1)"
fi
readarray -t release_sorted < <(printf '%s\n' "${release[@]}" | sort)
for dependency_version_files in 1\.2/*-dependency-version.json 2\.0/*-dependency-version.json; do
if [[ -f "${dependency_version_files}" ]]; then
sed -r 's/"revision": (.*)/PLACEHOLDER/g' -i "${dependency_version_files}"
dependency_version+=("${dependency_version_files}")
fi
done
readarray -t dependency_version_sorted < <(printf '%s\n' "${dependency_version[@]}" | sort)
paste -d '\n' "${release_sorted[@]}" | uniq | awk '!(NF && seen[$0]++) || /^>/' > "tmp-release.md"
paste -d '\n' "${dependency_version_sorted[@]}" | uniq | awk '!(NF && seen[$0]++)' > "dependency-version.json"
sed -i "s|PLACEHOLDER|\"revision\": \"${revision}\"|" dependency-version.json
./pandoc --wrap=preserve -f gfm tmp-release.md -t gfm -o release.md
- name: Host - Bootstrap release tag ${{ github.event.inputs.distinct_id }}
run: printf '%s\n' "release_tag=$(cat ${{ matrix.qbt_libtorrent_version }}/tag.md)" >> $GITHUB_ENV
- name: Host - Bootstrap release title ${{ github.event.inputs.distinct_id }}
run: printf '%s\n' "release_title=$(cat ${{ matrix.qbt_libtorrent_version }}/title.md)" >> $GITHUB_ENV
- name: Host- Create release - tag - assets ${{ github.event.inputs.distinct_id }}
uses: ncipollo/release-action@v1
with:
prerelease: "${{ matrix.preview_release }}"
artifacts: "${{ matrix.qbt_libtorrent_version }}/*-qbittorrent-nox,dependency-version.json"
replacesArtifacts: true
tag: "${{ env.release_tag }}"
name: "${{ env.release_title }}"
bodyFile: "release.md"
allowUpdates: true
token: "${{ github.TOKEN }}"
rerun-on-failure:
if: failure() && inputs.skip_rerun == '0'
name: rerun-on-failure
needs: release
permissions:
actions: write
runs-on: ubuntu-latest
env:
GH_TOKEN: "${{ github.TOKEN }}"
steps:
- uses: actions/checkout@v4
- name: Trigger rerun workflow on job failures
run: |
inputs_retries="${{ inputs.retries }}"
gh workflow run rerun.yml -f run_id=${{ github.run_id }} -f attempts=${{ github.run_attempt }} -f retries=${inputs_retries:-1}
rerun

This workflow automatically reruns any failed jobs. Mostly targeted for the release jobs to ensure the release is created.

name: rerun failed jobs with gh cli
on:
workflow_dispatch:
inputs:
run_id:
description: "The run id of the workflow to rerun"
required: true
attempts:
description: "The number of attempts to rerun the workflow"
required: true
retries:
description: "The number of retries to rerun the workflow"
required: true
jobs:
gh-cli-rerun:
name: rerun - attempt ${{ inputs.attempts }}
permissions:
actions: write
runs-on: ubuntu-latest
env:
GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
steps:
- name: Host - Checkout action
uses: actions/checkout@v4
- name: gh cli rerun and summaries
if: inputs.attempts <= inputs.retries
run: |
failures="$(gh run view ${{ inputs.run_id }} --log-failed | sed "s,\x1B\[[0-9;]*[a-zA-Z],,g")"
[[ -z "${failures}" ]] && failures="$(gh run view ${{ inputs.run_id }} | sed "s,\x1B\[[0-9;]*[a-zA-Z],,g")"
gh run rerun ${{ inputs.run_id }} --failed
printf '%b\n' "# gh cli workflow reruns" >> $GITHUB_STEP_SUMMARY
printf '\n%b\n' ":octocat: Here is a summary of inputs from the failed workflow" >> $GITHUB_STEP_SUMMARY
printf '\n%b\n' "πŸŸ₯ Failures at:\n\n\`\`\`log\n${failures}\n\`\`\`" >> $GITHUB_STEP_SUMMARY
printf '\n%b\n' "🟦 Attempt: ${{ inputs.attempts }} - Rerun failed jobs in ${{ inputs.run_id }} :hammer:" >> $GITHUB_STEP_SUMMARY
if gh run watch ${{ inputs.run_id }} --exit-status; then
printf '\n%b\n' "βœ… Attempt: ${{ inputs.attempts }} succeeded 😺" >> $GITHUB_STEP_SUMMARY
else
printf '\n%b\n' "❌ Attempt: ${{ inputs.attempts }} failed 😾" >> $GITHUB_STEP_SUMMARY
fi