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 required permissions for each workflow and job have been configured granularly in the workflows themselves. The permissions are defined in the permissions
section of the workflow.
Workflows
These workflows are using a reusable caller workflow that allows for inputs to be passed to the reusable workflows. This allows for a single workflow to be used to call multiple workflows with different inputs.
This is the structure of the workflows:
ci-main-reusable-caller├─ ci-debian-build├─ ci-alpine-build├─ ci-alpine-release└─ ci-auto-rerun-failed-jobs
ci-main-reusable-caller
The primary reusable caller workflow
# @credits https://github.com/c0re100/qBittorrent-Enhanced-Editionname: ci - main reusable caller
on: workflow_dispatch: inputs: script_name: description: "Which script to run?" required: true default: "qbt-nox-static.bash" type: choice options: ["qbt-nox-static.bash", "qbittorrent-nox-static.sh"] debian-build: description: "Debian: build" required: true default: false type: boolean alpine-build: description: "Alpine: build" required: true default: true type: boolean workflow-files: description: "Workflow files" required: true default: true type: boolean icu: description: "Enable icu" required: true default: false type: boolean debug: description: "Debug builds (symbols)" required: true default: false type: boolean release: description: "Release assets?" required: true default: true type: boolean distinct_id: description: "Distinct id" required: false type: string skip_rerun: description: "Skip rerun?" required: true default: false 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: {}
jobs: ci-debian-build: if: github.event.inputs.debian-build == 'true' concurrency: group: ci-debian-build cancel-in-progress: true permissions: contents: read uses: ./.github/workflows/ci-debian-build.yml with: distinct_id: ${{ github.event.inputs.distinct_id }} workflow-files: ${{ github.event.inputs.workflow-files == 'true' && 'yes' || 'no' }} icu: ${{ github.event.inputs.icu == 'true' && 'no' || 'yes' }} debug: ${{ github.event.inputs.debug == 'true' && 'yes' || 'no' }} script_name: ${{ github.event.inputs.script_name }}
ci-alpine-build: if: github.event.inputs.alpine-build == 'true' concurrency: group: ci-alpine-build cancel-in-progress: true permissions: id-token: write contents: read attestations: write uses: ./.github/workflows/ci-alpine-build.yml with: distinct_id: ${{ github.event.inputs.distinct_id }} workflow-files: ${{ github.event.inputs.workflow-files == 'true' && 'yes' || 'no' }} icu: ${{ github.event.inputs.icu == 'true' && 'no' || 'yes' }} debug: ${{ github.event.inputs.debug == 'true' && 'yes' || 'no' }} script_name: ${{ github.event.inputs.script_name }}
ci-alpine-release: needs: [ci-alpine-build] if: github.event.inputs.release == 'true' && contains(needs.*.result, 'success') && !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') concurrency: group: ci-alpine-release cancel-in-progress: true permissions: contents: write uses: ./.github/workflows/ci-alpine-release.yml with: distinct_id: ${{ github.event.inputs.distinct_id }}
ci-auto-rerun-failed-jobs: if: failure() && (github.event.inputs.skip_rerun || 'false') == 'false' needs: [ci-debian-build, ci-alpine-build, ci-alpine-release] concurrency: group: ci-auto-rerun-failed-jobs cancel-in-progress: true permissions: actions: write runs-on: ubuntu-24.04 env: GH_TOKEN: "${{ secrets.AUTO_RERUN || github.token }}" github_repo: "" # To use ci-auto-rerun-failed-jobs.yml hosted in a remote repository else default to the current repository. Requires PAT token AUTO_RERUN retries: ${{ github.event.inputs.retries || '1' }} distinct_id: ${{ github.event.inputs.distinct_id }} steps: - uses: actions/checkout@v4 with: persist-credentials: false - name: ci-auto-rerun-failed-jobs via ${{ env.github_repo || github.repository }} run: > gh workflow run ci-auto-rerun-failed-jobs-action.yml --repo "${github_repo:-$GITHUB_REPOSITORY}" -f github_repo=${GITHUB_REPOSITORY} -f run_id=${GITHUB_RUN_ID} -f attempts=${GITHUB_RUN_ATTEMPT} -f retries=${retries} -f distinct_id=${distinct_id}
ci-debian-build
The debian build workflow
name: ci - debian build
on: workflow_call: inputs: distinct_id: description: "Distinct id" required: false type: string workflow-files: description: "Alpine: workflow-files files" required: true type: string icu: description: "enable icu" required: true type: string debug: description: "debug builds" required: true type: string script_name: description: "script name" required: true type: string
jobs: build: defaults: run: shell: bash runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: container_id: [debian, ubuntu] container_codename: [bookworm, noble] qbt_build_tool: ["cmake", "qmake"] qbt_libtorrent_version: ["1.2", "2.0"] exclude: - container_id: debian container_codename: noble - 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: # host qbt_build_dir: "qbt-build" disable_qt5: "" artifact_name: "${{ matrix.container_id }}-${{ matrix.container_codename }}-${{ matrix.qbt_libtorrent_version }}-qt-${{ matrix.qbt_qt_version }}-${{ matrix.qbt_build_tool }}-nox" script_name: ${{ inputs.script_name }}
container: image: arm64v8/${{ matrix.container_id }}:${{ matrix.container_codename }} env: # container LANG: C.UTF-8 LC_ALL: C.UTF-8 DEBIAN_FRONTEND: noninteractive disable_qt5: ${{ env.disable_qt5 }} qbt_build_dir: ${{ env.qbt_build_dir }} qbt_libtorrent_version: ${{ matrix.qbt_libtorrent_version }} qbt_qt_version: ${{ matrix.qbt_qt_version }} qbt_build_tool: ${{ matrix.qbt_build_tool }} qbt_cross_name: ${{ matrix.qbt_cross_name }} qbt_patches_url: ${{ github.repository }} qbt_skip_icu: ${{ inputs.icu }} qbt_boost_tag: ${{ matrix.qbt_boost_tag }} qbt_libtorrent_tag: ${{ matrix.qbt_libtorrent_tag }} qbt_qt_tag: ${{ matrix.qbt_qt_tag }} qbt_qbittorrent_tag: ${{ matrix.qbt_qbittorrent_tag }} qbt_libtorrent_master_jamfile: "" qbt_workflow_files: ${{ inputs.workflow-files }} qbt_workflow_artifacts: "" qbt_cache_dir: "" qbt_optimise_strip: "" qbt_build_debug: ${{ inputs.debug }} qbt_revision_url: ${{ github.repository }} qbt_standard: "" qbt_static_ish: "" steps: - name: Checkout ${{ inputs.distinct_id }} uses: actions/checkout@v4 with: persist-credentials: false
- name: Bootstrap test tools ${{ inputs.distinct_id }} run: bash ${script_name} update install_test
- name: qBittorrent v5 transition ${{ inputs.distinct_id }} run: | if [[ -f "${qbt_build_dir}/release_info/disable-qt5" || -f "disable-qt5" ]]; then printf '%s\n' "disable_qt5=yes" >> $GITHUB_ENV printf '%s\n' "Found file: \`disable-qt5\` -> setting env: \`disable_qt5=yes\`" >> $GITHUB_STEP_SUMMARY fi
- name: Bootstrap core deps ${{ inputs.distinct_id }} if: env.disable_qt5 != 'yes' run: bash ${script_name} install_core
- name: Bootstrap build ${{ inputs.distinct_id }} if: env.disable_qt5 != 'yes' run: bash ${script_name} -bs-a
- name: glibc ${{ inputs.distinct_id }} if: env.disable_qt5 != 'yes' run: bash ${script_name} glibc
- name: zlib ${{ inputs.distinct_id }} if: env.disable_qt5 != 'yes' run: bash ${script_name} zlib
- name: iconv ${{ inputs.distinct_id }} if: env.disable_qt5 != 'yes' run: bash ${script_name} iconv
- name: icu ${{ inputs.distinct_id }} if: env.disable_qt5 != 'yes' run: bash ${script_name} icu
- name: openssl ${{ inputs.distinct_id }} if: env.disable_qt5 != 'yes' run: bash ${script_name} openssl
- name: boost ${{ inputs.distinct_id }} if: env.disable_qt5 != 'yes' run: bash ${script_name} boost
- name: libtorrent ${{ inputs.distinct_id }} if: env.disable_qt5 != 'yes' run: bash ${script_name} libtorrent
- name: double conversion ${{ inputs.distinct_id }} if: env.disable_qt5 != 'yes' && matrix.qbt_build_tool == 'cmake' run: bash ${script_name} double_conversion
- name: qtbase ${{ inputs.distinct_id }} if: env.disable_qt5 != 'yes' run: bash ${script_name} qtbase
- name: qttools ${{ inputs.distinct_id }} if: env.disable_qt5 != 'yes' run: bash ${script_name} qttools
- name: qbittorrent ${{ inputs.distinct_id }} if: env.disable_qt5 != 'yes' run: bash ${script_name} qbittorrent
- name: Upload ${{ env.artifact_name }} artifacts ${{ inputs.distinct_id }} if: env.disable_qt5 != 'yes' uses: actions/upload-artifact@v4 with: name: ${{ env.artifact_name }} path: ${{ env.qbt_build_dir }}/completed/qbittorrent-nox
- name: Host - Upload logs on error if: failure() && env.disable_qt5 != 'yes' uses: actions/upload-artifact@v4 with: name: "${{ env.artifact_name }}-logs" path: "${{ env.qbt_build_dir }}"
ci-alpine-build
The alpine build workflow
# @credits https://github.com/c0re100/qBittorrent-Enhanced-Editionname: ci - alpine build
on: workflow_call: inputs: distinct_id: description: "Distinct id" required: false type: string workflow-files: description: "Alpine: workflow-files files" required: true type: string icu: description: "enable icu" required: true type: string debug: description: "debug builds" required: true type: string script_name: description: "script name" required: true type: stringjobs: build-alpine: runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: os_id: [alpine] os_version_id: [edge] 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" script_name: ${{ inputs.script_name }} container_name: "multiarch"
steps: - name: Checkout ${{ inputs.distinct_id }} uses: actions/checkout@v4 with: persist-credentials: false
- name: Host - Create Docker template env file ${{ inputs.distinct_id }} env: set_skip_icu: ${{ inputs.icu }} set_workflow_files: ${{ inputs.workflow-files }} set_build_debug: ${{ inputs.debug }} run: | printf '%s\n' "qbt_build_dir=${{ env.qbt_build_dir }}" > env.custom 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=${set_skip_icu}" >> 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=" >> env.custom printf '%s\n' "qbt_workflow_files=${set_workflow_files}" >> env.custom printf '%s\n' "qbt_workflow_artifacts=" >> env.custom printf '%s\n' "qbt_cache_dir=" >> env.custom printf '%s\n' "qbt_optimise_strip=" >> env.custom printf '%s\n' "qbt_build_debug=${set_build_debug}" >> env.custom printf '%s\n' "qbt_revision_url=${{ github.repository }}" >> env.custom printf '%s\n' "qbt_standard=" >> env.custom printf '%s\n' "qbt_static_ish=" >> env.custom
# - name: Host - Github env to container ${{ inputs.distinct_id }} # run: env >> env.custom
- name: Host - check stuff ${{ inputs.distinct_id }} run: export $(cat env.custom) && bash ${script_name}
- name: Host - qBittorrent v5 transition ${{ inputs.distinct_id }} run: | if [[ -f "${qbt_build_dir}/release_info/disable-qt5" || -f "disable-qt5" ]]; then printf '%s\n' "disable_qt5=yes" >> $GITHUB_ENV printf '%s\n' "Found file: \`disable-qt5\` -> setting env: \`disable_qt5=yes\`" >> $GITHUB_STEP_SUMMARY fi
- name: Host - phased updates ${{ inputs.distinct_id }} if: env.disable_qt5 != 'yes' run: printf '%s\n' 'APT::Get::Always-Include-Phased-Updates "false";' | sudo tee /etc/apt/apt.conf.d/99-phased-updates
- name: Host - update ${{ inputs.distinct_id }} if: env.disable_qt5 != 'yes' run: sudo apt-get update
# - name: Host - upgrade ${{ inputs.distinct_id }} # run: sudo apt-get -y upgrade
- name: Host - set up qemu-user-static binfmt-support ${{ inputs.distinct_id }} if: env.disable_qt5 != 'yes' run: sudo apt install libpipeline1 qemu-user-static binfmt-support
- name: Host - Create docker ${{ env.multiarch }} container ${{ inputs.distinct_id }} if: env.disable_qt5 != 'yes' run: | # We create an Alpine edge container for cross-compilation with a user named gh which has same id as runner 1001 and provide sudo access # This way we can run commands as a non-root user, avoiding permission issues on host runner. Switching between user and root as needed. docker run --name ${container_name} -it -d --env-file env.custom -w /home/gh -v ${{ github.workspace }}:/home/gh ${{ matrix.os_id }}:${{ matrix.os_version_id }} # Create the user gh with the id 1001:1001 which is the same as the runner user id and group id. docker exec ${container_name} sh -c 'adduser -h /home/gh -Ds /bin/bash -u 1001 gh && apk add sudo' # Allow the user gh to run sudo without password prompt: docker exec -u gh:gh ${container_name} sudo ls docker exec ${container_name} sh -c 'printf "%s" "gh ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/gh'
- name: Docker - apk update ${{ inputs.distinct_id }} if: env.disable_qt5 != 'yes' run: docker exec ${container_name} apk update
- name: Docker - apk install bash ${{ inputs.distinct_id }} if: env.disable_qt5 != 'yes' run: docker exec ${container_name} apk add bash
- name: Docker - Bootstrap test tools ${{ inputs.distinct_id }} if: env.disable_qt5 != 'yes' run: docker exec ${container_name} bash ${script_name} update install_test
- name: Docker - Bootstrap core deps ${{ inputs.distinct_id }} if: env.disable_qt5 != 'yes' run: docker exec ${container_name} bash ${script_name} install_core
- name: Docker - Bootstrap build ${{ inputs.distinct_id }} if: env.disable_qt5 != 'yes' run: docker exec -u gh:gh ${container_name} bash ${script_name} -bs-a
- name: Docker - zlib-ng ${{ inputs.distinct_id }} if: env.disable_qt5 != 'yes' run: docker exec -u gh:gh ${container_name} bash ${script_name} zlib
- name: Docker - iconv ${{ inputs.distinct_id }} if: env.disable_qt5 != 'yes' run: docker exec -u gh:gh ${container_name} bash ${script_name} iconv
- name: Docker - icu ${{ inputs.distinct_id }} if: env.disable_qt5 != 'yes' run: docker exec -u gh:gh ${container_name} bash ${script_name} icu
- name: Docker - openssl ${{ inputs.distinct_id }} if: env.disable_qt5 != 'yes' run: docker exec -u gh:gh ${container_name} bash ${script_name} openssl
- name: Docker - boost ${{ inputs.distinct_id }} if: env.disable_qt5 != 'yes' run: docker exec -u gh:gh ${container_name} bash ${script_name} boost
- name: Docker - libtorrent ${{ inputs.distinct_id }} if: env.disable_qt5 != 'yes' run: docker exec -u gh:gh ${container_name} bash ${script_name} libtorrent
- name: Docker - double_conversion ${{ inputs.distinct_id }} if: matrix.qbt_build_tool == '' && env.disable_qt5 != 'yes' run: docker exec -u gh:gh ${container_name} bash ${script_name} double_conversion
- name: Docker - qtbase ${{ inputs.distinct_id }} if: env.disable_qt5 != 'yes' run: docker exec -u gh:gh ${container_name} bash ${script_name} qtbase
- name: Docker - qttools ${{ inputs.distinct_id }} if: env.disable_qt5 != 'yes' run: docker exec -u gh:gh ${container_name} bash ${script_name} qttools
- name: Docker - qbittorrent ${{ inputs.distinct_id }} if: env.disable_qt5 != 'yes' run: docker exec -u gh:gh ${container_name} bash ${script_name} qbittorrent
- name: Docker - Set release asset name ${{ inputs.distinct_id }} if: env.disable_qt5 != 'yes' run: docker exec -u gh:gh -w /home/gh/${{ env.qbt_build_dir }}/completed ${container_name} mv -f qbittorrent-nox ${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}qbittorrent-nox
- name: Generate artifact attestation ${{ inputs.distinct_id }} if: env.disable_qt5 != 'yes' uses: actions/attest-build-provenance@v2 with: subject-path: "${{ env.qbt_build_dir }}/completed/${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}qbittorrent-nox"
- name: Docker - Release Info ${{ inputs.distinct_id }} if: env.disable_qt5 != 'yes' run: docker exec -u gh:gh -w /home/gh/${{ env.qbt_build_dir }}/release_info ${container_name} bash -c 'mv *.md *.json '/home/gh/${{ env.qbt_build_dir }}/completed''
- name: Host - Upload libtorrent-v${{ matrix.qbt_libtorrent_version }}-qbittorrent-nox and release info artifact ${{ inputs.distinct_id }} if: success() && env.disable_qt5 != 'yes' 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 ${{ inputs.distinct_id }} if: success() && matrix.qbt_build_tool == '' && env.disable_qt5 != 'yes' 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"
- name: Host - Upload logs on error if: failure() && env.disable_qt5 != 'yes' uses: actions/upload-artifact@v4 with: name: "${{ matrix.qbt_cross_name }}-libtorrent-v${{ matrix.qbt_libtorrent_version }}-logs" path: "${{ env.qbt_build_dir }}/logs/*"
ci-alpine-release
The alpine release workflow
name: ci - alpine-release
on: workflow_call: inputs: distinct_id: description: "Distinct ID for the artifacts" required: true type: string
jobs: release: runs-on: ubuntu-24.04 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 ${{ inputs.distinct_id }} uses: actions/checkout@v4 with: persist-credentials: false
- 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-$(dpkg --print-architecture).tar.gz" | tar xzf - --strip-components 2 -C "$(pwd)" --exclude="share"
- name: Host - Download 1.2 qbittorrent-nox artifacts ${{ 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 ${{ 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 ${{ 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)" boost="$(jq -r .boost 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)" boost="$(jq -r .boost 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/"boost": (.*)/BOOST_PLACEHOLDER/g' -i "${dependency_version_files}" sed -r 's/"revision": (.*)/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|BOOST_PLACEHOLDER|\"boost\": \"${boost}\",|" dependency-version.json sed -i "s|REVISION_PLACEHOLDER|\"revision\": \"${revision}\"|" dependency-version.json
./pandoc --wrap=preserve -f gfm tmp-release.md -t gfm -o release.md
- name: Host - Bootstrap release tag ${{ inputs.distinct_id }} run: printf '%s\n' "release_tag=$(cat ${{ matrix.qbt_libtorrent_version }}/tag.md)" >> $GITHUB_ENV
- name: Host - Bootstrap release title ${{ inputs.distinct_id }} run: printf '%s\n' "release_title=$(cat ${{ matrix.qbt_libtorrent_version }}/title.md)" >> $GITHUB_ENV
- name: Host- Create release - tag - assets ${{ 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 }}"
ci-auto-rerun-failed-jobs-action
This workflow automatically reruns any failed jobs. Mostly targeted for the release jobs to ensure the release is created.
name: ci - auto rerun failed jobs
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 github_repo: description: "The repository to rerun the workflow" required: false distinct_id: description: "The distinct id of the workflow to rerun" required: false
run-name: ci auto rerun failed jobs - attempt ${{ inputs.attempts }}
jobs: gh-cli-rerun: name: rerun - attempt ${{ inputs.attempts }} permissions: actions: write runs-on: ubuntu-24.04 env: GH_TOKEN: "${{ secrets.AUTO_RERUN || github.token }}" steps: - name: Host - Checkout action ${{ inputs.distinct_id }} uses: actions/checkout@v4 with: persist-credentials: false
- uses: userdocs/gh-cli-workflow-reruns/actions/auto-rerun-failed@main with: run_id: ${{ inputs.run_id }} attempts: ${{ inputs.attempts }} retries: ${{ inputs.retries }} github_repo: ${{ inputs.github_repo || github.repository }} distinct_id: ${{ inputs.distinct_id || github.run_id }}