Skip to content

Commit f254d4e

Browse files
committed
v2.2.0 / v2.0.20
adding -static-pie qi.bash qi.bash
1 parent 06b2458 commit f254d4e

File tree

21 files changed

+3265
-1345
lines changed

21 files changed

+3265
-1345
lines changed

.github/copilot-instructions.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Bash Scripting - All repos
2+
3+
- use $BASH_SOURCE instead of $0
4+
- avoid set -euo pipefail - instead focus on thorough testing, validation and error handling.
5+
- ideally error handling should be considered holistically but per function is acceptable.
6+
- changes and recommendations should be simple, modular, focused on the requirement of the prompt.
7+
- never make generalized changes that are not specifically required for the prompt.
8+
- don't over complicated the solution or pollute it with noisy or complex solutions.
9+
- Always makes changes in stages, a modular approach.
10+
- use Google style guide for formatting of bash scripts - https://google.github.io/styleguide/shellguide.html
11+
- Always use `#!/bin/bash` as the shebang.
12+
- Use `printf '%s'` for printing strings and `printf '%b'` for escape sequences. **Avoid using `echo`.**
13+
- Comment code to explain changes and logic.
14+
- always prefer readability of code over complex one lines. Unless that foramt is promoted by the style guide.
15+
- For Bash/shell questions, consult [mywiki.wooledge.org](https://mywiki.wooledge.org) or [BashFAQ](https://mywiki.wooledge.org/BashFAQ) first. **Provide a source link when possible.**
16+
17+
# GitHub Workflows - All repos
18+
19+
- In reusable workflows, jobs that use outputs from other jobs **must** include those jobs in their `needs` section to avoid null variables.
20+
- Do not use outdated GitHub Actions in workflow code. Always check the version recommended is the current version
21+
- The `gh` CLI cannot get the ID of a workflow it started with `gh run workflow`; you must list runs after and extract the ID.
22+
23+
# If repo = *-musl-cross-make
24+
GCC / Binutils
25+
- Use both `-static` and `--static` to create static toolchain binaries. Using `-static` alone can cause errors (e.g., missing POSIX threads).
26+
- When working with `../config.mak`, always load options from both `../gcc-configure-options.md` and `../gcc-configure-options-recursive.md`.
27+
- The binutils gold linker is deprecated. Use `ld=default` and `--disable-gold`.
28+
- For fully static toolchains linked to musl:
29+
- Do **not** use `-flto` or `-fuse-linker-plugin` (LTO is not supported; plugins require dynamic loading).
30+
- Do **not** add any LTO settings.
31+
- Only set linker options like `LDFLAGS` when linking, **not** when building libraries.
32+
- GNU libtool redefines `-static`; to ensure static linking, use `--static` or `-Wl,-static` in `LDFLAGS` (possibly with `-static`).
33+
- When building OpenSSL statically, do **not** use `openssl -static` (it disables threads, PIE, PIC). For `-static-pie` binaries with musl/Alpine, use the correct flags.
34+
- Do **not** suggest glibc-only flags or glibcisms for musl toolchains.
35+
36+
# Debugging with qemu
37+
38+
- To debug with QEMU:
39+
Run `qemu -g <port> <binary>` (e.g., `qemu -g 1234 ./qbt-nox-static`), then connect with `gdb ./qbt-nox-static` in another terminal.
40+
41+
# If repo = * qbittorrent-nox-static
42+
43+
## qi.bash script
44+
45+
General features
46+
- Always use `#!/bin/bash` as the shebang.
47+
- this script is focused on being a simple installer that verifies installation and binaries.
48+
49+
basic check for supported os
50+
- use source /etc/os-release
51+
- if ID = alpine of debian or if the or if ID_LIKE=debian is debian like we can proceed.
52+
- if not supported os exit with reason.
53+
54+
basic check for wget or curl, default to curl if present.
55+
- if no tools exit with reason.
56+
- wget or curl must have, curl default if present but use wget if there.
57+
- check if gh cli is available to use but no required.
58+
59+
basic check of which arch using
60+
- alpine use apk --print-arch
61+
- debian like use dpkg --print-architecture
62+
- all arches are the same except armhf. on debian this is armv7 and alpine armv6
63+
- if not valid arch exit with reason.
64+
65+
create download function based on arch checks.
66+
- configure download url based on arch.
67+
- creates sha256 of download.
68+
69+
gh cli function
70+
- if gh cli exists and is usable use it to very the binaries downloaded
71+
- if gh attestation verify <INSTALL_PATH> --repo <REPO> 2> /dev/null; then ...
72+
73+
error handling
74+
- there should be a error handling function to test commands exit the script with helpful explanations when a command or function fails.
75+
76+
ouputs
77+
- there should be a function to handle printing outputs.
78+
- It should handle [INFO] (blue) [WARNING] (yellow) [ERROR] (red) [SUCCESS] (Green) [FAILURE] (magenta)
79+
- Use `printf '%s'` for printing strings and `printf '%b'` for escape sequences. **Avoid using `echo`.**
80+
- this function will provide end user information understanding or troubleshooting script outcomes.
81+
- it should be succinct unless there is an error or failure, then it should be verbose enough to help.
Lines changed: 78 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
# @credits https://github.com/c0re100/qBittorrent-Enhanced-Edition
21
name: ci - alpine build
32

43
on:
@@ -24,184 +23,164 @@ on:
2423
description: "script name"
2524
required: true
2625
type: string
26+
2727
jobs:
28-
build-alpine:
29-
runs-on: ubuntu-24.04-arm
28+
build:
29+
runs-on: ${{ matrix.runs_on }}
3030
strategy:
3131
fail-fast: false
3232
matrix:
33+
runs_on: ["ubuntu-24.04-arm"]
3334
os_id: [alpine]
3435
os_version_id: [edge]
3536
qbt_cross_name: ["armhf", "armv7", "aarch64", "riscv64", "x86_64", "x86"]
3637
qbt_libtorrent_version: ["1.2", "2.0"]
37-
qbt_build_tool: ["", "qmake"]
38+
qbt_build_tool: [""]
39+
qbt_qbittorrent_tag: [""]
3840
include:
39-
- qbt_build_tool: "qmake"
40-
qbt_qt_version_name: "qt5-"
41-
qbt_qt_version: "5"
4241
- qbt_build_tool: ""
4342
qbt_qt_version_name: ""
44-
qbt_qt_version: "6"
4543

4644
name: "${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}libtorrent-v${{ matrix.qbt_libtorrent_version }}"
4745

4846
env:
4947
qbt_build_dir: "qbt-build"
50-
script_name: ${{ inputs.script_name }}
5148
container_name: "multiarch"
49+
script_name: ${{ inputs.script_name }}
50+
set_skip_icu: ${{ inputs.icu }}
51+
set_workflow_files: ${{ inputs.workflow-files }}
52+
set_build_debug: ${{ inputs.debug }}
53+
set_qbt_mcm_url: "" # default is userdocs/qbt-musl-cross-make
54+
set_qbt_with_qemu: "" # default is yes
55+
set_qbt_host_deps: "" # default is no
56+
set_qbt_host_deps_repo: "" # default is userdocs/qbt-host-deps
5257

5358
steps:
5459
- name: Checkout ${{ inputs.distinct_id }}
5560
uses: actions/checkout@v4
5661
with:
5762
persist-credentials: false
5863

64+
- name: Download ${{ env.script_name }}
65+
run: |
66+
# Make sure the branch is set to master for qbittorrent-nox-static and main qbittorrent-nox-static-test
67+
if [[ ! -f "${script_name}" ]]; then
68+
echo "Downloading ${script_name} from userdocs/qbittorrent-nox-static"
69+
curl -LO "https://raw.githubusercontent.com/userdocs/qbittorrent-nox-static/refs/heads/master/${script_name}"
70+
chmod +x "${script_name}"
71+
fi
72+
5973
- name: Host - Create Docker template env file ${{ inputs.distinct_id }}
60-
env:
61-
set_skip_icu: ${{ inputs.icu }}
62-
set_workflow_files: ${{ inputs.workflow-files }}
63-
set_build_debug: ${{ inputs.debug }}
6474
run: |
65-
printf '%s\n' "qbt_build_dir=${{ env.qbt_build_dir }}" > env.custom
66-
printf '%s\n' "qbt_libtorrent_version=${{ matrix.qbt_libtorrent_version }}" >> env.custom
67-
printf '%s\n' "qbt_qt_version=${{ matrix.qbt_qt_version }}" >> env.custom
68-
printf '%s\n' "qbt_build_tool=${{ matrix.qbt_build_tool }}" >> env.custom
69-
printf '%s\n' "qbt_cross_name=${{ matrix.qbt_cross_name }}" >> env.custom
70-
printf '%s\n' "qbt_patches_url=${{ github.repository }}" >> env.custom
75+
printf '%s\n' "qbt_revision_url=${{ github.repository }}" > env.custom
76+
printf '%s\n' "qbt_zlib_type=zlib" >> env.custom
7177
printf '%s\n' "qbt_skip_icu=${set_skip_icu}" >> env.custom
7278
printf '%s\n' "qbt_boost_tag=${{ matrix.qbt_boost_tag }}" >> env.custom
79+
printf '%s\n' "qbt_libtorrent_version=${{ matrix.qbt_libtorrent_version }}" >> env.custom
7380
printf '%s\n' "qbt_libtorrent_tag=${{ matrix.qbt_libtorrent_tag }}" >> env.custom
81+
printf '%s\n' "qbt_libtorrent_master_jamfile=" >> env.custom
82+
printf '%s\n' "qbt_qt_version=${{ matrix.qbt_qt_version }}" >> env.custom
7483
printf '%s\n' "qbt_qt_tag=${{ matrix.qbt_qt_tag }}" >> env.custom
7584
printf '%s\n' "qbt_qbittorrent_tag=${{ matrix.qbt_qbittorrent_tag }}" >> env.custom
76-
printf '%s\n' "qbt_libtorrent_master_jamfile=" >> env.custom
85+
printf '%s\n' "qbt_build_dir=${qbt_build_dir}" >> env.custom
86+
printf '%s\n' "qbt_build_tool=${{ matrix.qbt_build_tool }}" >> env.custom
87+
printf '%s\n' "qbt_cross_name=${{ matrix.qbt_cross_name }}" >> env.custom
88+
printf '%s\n' "qbt_mcm_url=${set_qbt_mcm_url}" >> env.custom
89+
printf '%s\n' "qbt_patches_url=${{ github.repository }}" >> env.custom
7790
printf '%s\n' "qbt_workflow_files=${set_workflow_files}" >> env.custom
78-
printf '%s\n' "qbt_workflow_artifacts=" >> env.custom
7991
printf '%s\n' "qbt_cache_dir=" >> env.custom
8092
printf '%s\n' "qbt_optimise_strip=" >> env.custom
8193
printf '%s\n' "qbt_build_debug=${set_build_debug}" >> env.custom
82-
printf '%s\n' "qbt_revision_url=${{ github.repository }}" >> env.custom
8394
printf '%s\n' "qbt_standard=" >> env.custom
8495
printf '%s\n' "qbt_static_ish=" >> env.custom
96+
printf '%s\n' "qbt_optimise=${qbt_optimise}" >> env.custom
97+
printf '%s\n' "qbt_with_qemu=${set_qbt_with_qemu}" >> env.custom
98+
printf '%s\n' "qbt_host_deps=${set_qbt_host_deps}" >> env.custom
99+
printf '%s\n\n' "qbt_host_deps_repo=${set_qbt_host_deps_repo}" >> env.custom
85100
86-
# - name: Host - Github env to container ${{ inputs.distinct_id }}
87-
# run: env >> env.custom
88-
89-
- name: Host - check stuff ${{ inputs.distinct_id }}
90-
run: export $(cat env.custom) && bash ${script_name}
91-
92-
- name: Host - qBittorrent v5 transition ${{ inputs.distinct_id }}
101+
- name: Host - Debian based specific env ${{ inputs.distinct_id }}
102+
if : matrix.os_id != 'alpine'
93103
run: |
94-
if [[ -f "${qbt_build_dir}/release_info/disable-qt5" || -f "disable-qt5" ]]; then
95-
printf '%s\n' "disable_qt5=yes" >> $GITHUB_ENV
96-
printf '%s\n' "Found file: \`disable-qt5\` -> setting env: \`disable_qt5=yes\`" >> $GITHUB_STEP_SUMMARY
97-
fi
98-
99-
- name: Host - phased updates ${{ inputs.distinct_id }}
100-
if: env.disable_qt5 != 'yes'
101-
run: printf '%s\n' 'APT::Get::Always-Include-Phased-Updates "false";' | sudo tee /etc/apt/apt.conf.d/99-phased-updates
102-
103-
- name: Host - update ${{ inputs.distinct_id }}
104-
if: env.disable_qt5 != 'yes'
105-
run: sudo apt-get update
106-
107-
# - name: Host - upgrade ${{ inputs.distinct_id }}
108-
# run: sudo apt-get -y upgrade
104+
printf '%s\n' "LANG=C.UTF-8" >> env.custom
105+
printf '%s\n' "LC_ALL=C.UTF-8" >> env.custom
106+
printf '%s\n\n' "DEBIAN_FRONTEND=noninteractive" >> env.custom
109107
110-
- name: Host - set up qemu-user-static binfmt-support ${{ inputs.distinct_id }}
111-
if: env.disable_qt5 != 'yes'
112-
run: sudo apt install libpipeline1 qemu-user-static binfmt-support
108+
- name: Host - Bootstrap qemu
109+
uses: userdocs/actions/qemu@main
113110

114-
- name: Host - Create docker ${{ env.multiarch }} container ${{ inputs.distinct_id }}
115-
if: env.disable_qt5 != 'yes'
116-
run: |
117-
# 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
118-
# This way we can run commands as a non-root user, avoiding permission issues on host runner. Switching between user and root as needed.
119-
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 }}
120-
# Create the user gh with the id 1001:1001 which is the same as the runner user id and group id.
121-
docker exec ${container_name} sh -c 'adduser -h /home/gh -Ds /bin/bash -u 1001 gh && apk add sudo'
122-
# Allow the user gh to run sudo without password prompt: docker exec -u gh:gh ${container_name} sudo ls
123-
docker exec ${container_name} sh -c 'printf "%s" "gh ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/gh'
111+
- uses: userdocs/actions/qbt_docker@main
112+
with:
113+
# if the env.custom file exists, it will be used to pass environment
114+
distinct_id: ${{ inputs.distinct_id }}
115+
use_host_env: "false"
116+
container_name: ${{ env.container_name }}
117+
os_id: ${{ matrix.os_id }}
118+
os_version_id: ${{ matrix.os_version_id }}
119+
custom_docker_commands: ""
120+
additional_alpine_apps: "bash curl git"
121+
additional_debian_apps: "bash curl git"
124122

125123
- name: Host - patches ${{ inputs.distinct_id }}
126-
if: env.disable_qt5 != 'yes'
127-
run: mkdir -p ${qbt_build_dir}/patches && cp -r patches/* ${qbt_build_dir}/patches/
128-
129-
- name: Docker - apk update ${{ inputs.distinct_id }}
130-
if: env.disable_qt5 != 'yes'
131-
run: docker exec ${container_name} apk update
132-
133-
- name: Docker - apk install bash ${{ inputs.distinct_id }}
134-
if: env.disable_qt5 != 'yes'
135-
run: docker exec ${container_name} apk add bash
124+
if: hashFiles('patches/**') != ''
125+
run: mkdir -p ${qbt_build_dir}/patches && cp -rf patches/* ${qbt_build_dir}/patches/
136126

137-
- name: Docker - Bootstrap test tools ${{ inputs.distinct_id }}
138-
if: env.disable_qt5 != 'yes'
139-
run: docker exec ${container_name} bash ${script_name} update install_test
140-
141-
- name: Docker - Bootstrap core deps ${{ inputs.distinct_id }}
142-
if: env.disable_qt5 != 'yes'
143-
run: docker exec ${container_name} bash ${script_name} install_core
127+
- name: Docker - bootstrap_deps ${{ inputs.distinct_id }}
128+
if: inputs.script_name == 'qbt-nox-static.bash'
129+
run: docker exec -u gh:gh ${container_name} bash ${script_name} bootstrap_deps
144130

145131
- name: Docker - Bootstrap build ${{ inputs.distinct_id }}
146-
if: env.disable_qt5 != 'yes'
147132
run: docker exec -u gh:gh ${container_name} bash ${script_name} -bs-a
148133

149-
- name: Docker - zlib-ng ${{ inputs.distinct_id }}
150-
if: env.disable_qt5 != 'yes'
134+
- name: Docker - glibc ${{ inputs.distinct_id }}
135+
if : matrix.os_id != 'alpine'
136+
run: docker exec -u gh:gh ${container_name} bash ${script_name} glibc
137+
138+
- name: Docker - zlib ${{ inputs.distinct_id }}
151139
run: docker exec -u gh:gh ${container_name} bash ${script_name} zlib
152140

153141
- name: Docker - iconv ${{ inputs.distinct_id }}
154-
if: env.disable_qt5 != 'yes'
142+
if: matrix.qbt_libtorrent_version == '1.2'
155143
run: docker exec -u gh:gh ${container_name} bash ${script_name} iconv
156144

157145
- name: Docker - icu ${{ inputs.distinct_id }}
158-
if: env.disable_qt5 != 'yes'
146+
if: env.set_skip_icu == 'no'
159147
run: docker exec -u gh:gh ${container_name} bash ${script_name} icu
160148

161149
- name: Docker - openssl ${{ inputs.distinct_id }}
162-
if: env.disable_qt5 != 'yes'
163150
run: docker exec -u gh:gh ${container_name} bash ${script_name} openssl
164151

165152
- name: Docker - boost ${{ inputs.distinct_id }}
166-
if: env.disable_qt5 != 'yes'
167153
run: docker exec -u gh:gh ${container_name} bash ${script_name} boost
168154

169155
- name: Docker - libtorrent ${{ inputs.distinct_id }}
170-
if: env.disable_qt5 != 'yes'
171156
run: docker exec -u gh:gh ${container_name} bash ${script_name} libtorrent
172157

173158
- name: Docker - double_conversion ${{ inputs.distinct_id }}
174-
if: matrix.qbt_build_tool == '' && env.disable_qt5 != 'yes'
159+
if: matrix.qbt_build_tool == ''
175160
run: docker exec -u gh:gh ${container_name} bash ${script_name} double_conversion
176161

177162
- name: Docker - qtbase ${{ inputs.distinct_id }}
178-
if: env.disable_qt5 != 'yes'
179163
run: docker exec -u gh:gh ${container_name} bash ${script_name} qtbase
180164

181165
- name: Docker - qttools ${{ inputs.distinct_id }}
182-
if: env.disable_qt5 != 'yes'
183166
run: docker exec -u gh:gh ${container_name} bash ${script_name} qttools
184167

185168
- name: Docker - qbittorrent ${{ inputs.distinct_id }}
186-
if: env.disable_qt5 != 'yes'
187169
run: docker exec -u gh:gh ${container_name} bash ${script_name} qbittorrent
188170

189171
- name: Docker - Set release asset name ${{ inputs.distinct_id }}
190-
if: env.disable_qt5 != 'yes'
191-
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
172+
run: docker exec -u gh:gh -w /home/gh/${qbt_build_dir}/completed ${container_name} mv -f qbittorrent-nox ${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}qbittorrent-nox
192173

193174
- name: Generate artifact attestation ${{ inputs.distinct_id }}
194-
if: env.disable_qt5 != 'yes'
195175
uses: actions/attest-build-provenance@v2
196176
with:
197177
subject-path: "${{ env.qbt_build_dir }}/completed/${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}qbittorrent-nox"
198178

199179
- name: Docker - Release Info ${{ inputs.distinct_id }}
200-
if: env.disable_qt5 != 'yes'
201-
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''
180+
run: docker exec -u gh:gh -w /home/gh/${qbt_build_dir}/release_info ${container_name} bash -c 'mv *.md *.json '/home/gh/${qbt_build_dir}/completed''
202181

203182
- name: Host - Upload libtorrent-v${{ matrix.qbt_libtorrent_version }}-qbittorrent-nox and release info artifact ${{ inputs.distinct_id }}
204-
if: success() && env.disable_qt5 != 'yes'
183+
if: success()
205184
uses: actions/upload-artifact@v4
206185
with:
207186
name: libtorrent-v${{ matrix.qbt_libtorrent_version }}-${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}qbittorrent-nox
@@ -210,15 +189,15 @@ jobs:
210189
!${{ env.qbt_build_dir }}/completed/*.png
211190
212191
- name: Host - Upload cmake graphs artifact ${{ inputs.distinct_id }}
213-
if: success() && matrix.qbt_build_tool == '' && env.disable_qt5 != 'yes'
192+
if: success() && matrix.qbt_build_tool == ''
214193
uses: actions/upload-artifact@v4
215194
with:
216195
name: "${{ matrix.qbt_cross_name }}-libtorrent-v${{ matrix.qbt_libtorrent_version }}-graphs"
217196
path: "${{ env.qbt_build_dir }}/completed/*.png"
218197

219-
- name: Host - Upload logs on error
220-
if: failure() && env.disable_qt5 != 'yes'
221-
uses: actions/upload-artifact@v4
222-
with:
223-
name: "${{ matrix.qbt_cross_name }}-libtorrent-v${{ matrix.qbt_libtorrent_version }}-logs"
224-
path: "${{ env.qbt_build_dir }}/logs/*"
198+
# - name: Host - Upload build dir on error or cancel
199+
# if: ( cancelled() || failure() )
200+
# uses: actions/upload-artifact@v4
201+
# with:
202+
# name: "${{ matrix.qbt_cross_name }}-libtorrent-v${{ matrix.qbt_libtorrent_version }}-logs"
203+
# path: "${{ env.qbt_build_dir }}"

0 commit comments

Comments
 (0)