Skip to content

Commit f6ecb93

Browse files
committed
large test
1 parent 59cb4ae commit f6ecb93

15 files changed

Lines changed: 207 additions & 173 deletions

File tree

.dockerignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
*
2+
!.github/
3+
!.github/qt_helper.py

.github/qt_helper.py

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
#!/usr/bin/env python3
2+
import argparse
3+
import fnmatch
24
import hashlib
35
import mmap
46
import pathlib
@@ -10,7 +12,7 @@
1012

1113
MAX_TRIES = 32
1214

13-
def fetch_links_to_archives(os, target, major, minor, patch, toolchain):
15+
def fetch_links_to_archives(os, target, major, minor, patch, toolchain, packages):
1416
MAX_XML_SIZE = 1024 * 1024 * 1024
1517
MIRROR = 'download.qt.io'
1618
qt_dir = f'qt{major}_{major}{minor}{patch}'
@@ -30,12 +32,20 @@ def fetch_links_to_archives(os, target, major, minor, patch, toolchain):
3032
else:
3133
return
3234

35+
package_prefix = f'qt.qt{major}.{major}{minor}{patch}'
36+
package_names = {
37+
f'{package_prefix}.{package}.{toolchain}' if package else f'{package_prefix}.{toolchain}'
38+
for package in packages
39+
}
40+
41+
found_packages = set()
3342
for pkg in update_xml.findall('./PackageUpdate'):
3443
name = pkg.find('.//Name')
3544
if name == None:
3645
continue
37-
if name.text != f'qt.qt{major}.{major}{minor}{patch}.{toolchain}':
46+
if name.text not in package_names:
3847
continue
48+
found_packages.add(name.text)
3949
version = pkg.find('.//Version')
4050
if version == None:
4151
continue
@@ -48,7 +58,11 @@ def fetch_links_to_archives(os, target, major, minor, patch, toolchain):
4858
continue
4959
url = f'{base_url}/{name.text}/{version.text}{archive}'
5060
file_name = pathlib.Path(urllib.parse.urlparse(url).path).name
51-
yield {'name': file_name, 'url': url}
61+
yield {'name': file_name, 'url': url, 'archive': archive}
62+
63+
missing_packages = package_names - found_packages
64+
if missing_packages:
65+
raise RuntimeError(f'Qt packages not found: {", ".join(sorted(missing_packages))}')
5266

5367
def download(links):
5468
metalink = ET.Element('metalink', xmlns = "urn:ietf:params:xml:ns:metalink")
@@ -94,24 +108,47 @@ def calc_hash_sum(files):
94108

95109
def extract_archives(files, out='.', targets=[]):
96110
for path in files:
97-
if subprocess.Popen(['7z', 'x', '-bd', '-y', '-aoa', f'-o{out}', path] + targets,
111+
print('extracting', path, flush=True)
112+
if subprocess.Popen(['bsdtar', '-xf', path, '-C', out] + targets,
98113
stdout=subprocess.DEVNULL,
99114
).wait() != 0:
100115
return False
101116
return True
102117

103118
def main():
104-
os, target, version, toolchain, expect = sys.argv[1:]
119+
parser = argparse.ArgumentParser()
120+
parser.add_argument('os')
121+
parser.add_argument('target')
122+
parser.add_argument('version')
123+
parser.add_argument('toolchain')
124+
parser.add_argument('expect')
125+
parser.add_argument('--add-package', action='append', default=[],
126+
help='additional package below qt.qt<major>.<version>, such as addons.qtshadertools')
127+
parser.add_argument('--archive', action='append', default=[],
128+
help='fnmatch pattern selecting archives from the requested packages')
129+
args = parser.parse_args()
130+
131+
os, target, version, toolchain, expect = (
132+
args.os, args.target, args.version, args.toolchain, args.expect
133+
)
105134
major, minor, patch = version.split('.')
106135

107-
links = [*fetch_links_to_archives(os, target, major, minor, patch, toolchain)]
136+
packages = [''] + args.add_package
137+
links = [*fetch_links_to_archives(os, target, major, minor, patch, toolchain, packages)]
138+
if args.archive:
139+
links = [
140+
link for link in links
141+
if any(fnmatch.fnmatch(link['archive'], pattern) for pattern in args.archive)
142+
]
143+
if not links:
144+
raise RuntimeError('No Qt archives matched')
108145
print(*[l['url'].encode() for l in links], sep='\n', flush=True)
109146

110147
assert download(links)
111148

112149
result = calc_hash_sum([l['name'] for l in links])
113150
print('result', result, 'expect', expect, flush=True)
114-
assert result == expect
151+
assert expect == '-' or result == expect
115152

116153
assert extract_archives([l['name'] for l in links], '.')
117154

.github/workflows/build.yml

Lines changed: 38 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,21 @@ env:
88
99
jobs:
1010
build-macos:
11+
if: false
1112
runs-on: macos-latest
1213
steps:
1314
- uses: actions/checkout@v7
1415
with:
1516
submodules: recursive
1617
- name: install dependencies
1718
run: HOMEBREW_NO_AUTO_UPDATE=1 brew install boost ccache hidapi openssl zmq libsodium miniupnpc unbound libunwind-headers protobuf qt pkg-config
18-
- name: configure
19-
run: cmake -S . -B build/ci -DDEV_MODE=ON -DWITH_SCANNER=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$(brew --prefix qt)" -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
2019
- name: build
21-
run: cmake --build build/ci --target monero-wallet-gui -j8
20+
run: DEV_MODE=ON make release -j3
2221
- name: test qml
23-
run: build/ci/bin/monero-wallet-gui.app/Contents/MacOS/monero-wallet-gui --test-qml
22+
run: build/release/bin/monero-wallet-gui.app/Contents/MacOS/monero-wallet-gui --test-qml
2423

2524
build-ubuntu:
25+
if: false
2626
runs-on: ubuntu-26.04
2727
steps:
2828
- uses: actions/checkout@v7
@@ -38,15 +38,17 @@ jobs:
3838
- name: update apt
3939
run: sudo apt update
4040
- name: install monero dependencies
41-
run: sudo apt -y install build-essential ccache cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev libzmq3-dev libsodium-dev libhidapi-dev libnorm-dev libusb-1.0-0-dev libpgm-dev libprotobuf-dev protobuf-compiler libgcrypt20-dev qt6-base-dev qt6-declarative-dev qt6-svg-dev qt6-tools-dev qt6-tools-dev-tools qml6-module-qtcore qml6-module-qtqml qml6-module-qtqml-models qml6-module-qtquick qml6-module-qtquick-controls qml6-module-qtquick-dialogs qml6-module-qtquick-effects qml6-module-qtquick-layouts qml6-module-qtquick-shapes qml6-module-qtquick-window qml6-module-qt-labs-folderlistmodel qml6-module-qt-labs-platform qml6-module-qtmultimedia xvfb libgl1 libegl1 libxkbcommon-x11-0 libxcb-cursor0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0
42-
- name: configure
43-
run: cmake -S . -B build/ci -DDEV_MODE=ON -DWITH_SCANNER=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
41+
run: sudo apt -y install build-essential ccache cmake libboost-all-dev miniupnpc libunbound-dev libunwind8-dev pkg-config libssl-dev libzmq3-dev libsodium-dev libhidapi-dev libusb-1.0-0-dev libprotobuf-dev protobuf-compiler libgcrypt20-dev qt6-base-dev qt6-declarative-dev qt6-svg-dev qt6-tools-dev qt6-tools-dev-tools qml6-module-qtcore qml6-module-qtqml qml6-module-qtqml-models qml6-module-qtquick qml6-module-qtquick-controls qml6-module-qtquick-dialogs qml6-module-qtquick-effects qml6-module-qtquick-layouts qml6-module-qtquick-shapes qml6-module-qtquick-window qml6-module-qt-labs-folderlistmodel qml6-module-qt-labs-platform
4442
- name: build
45-
run: cmake --build build/ci --target monero-wallet-gui -j8
43+
run: DEV_MODE=ON make release -j4
4644
- name: test qml
47-
run: xvfb-run -a build/ci/bin/monero-wallet-gui --test-qml
45+
env:
46+
QT_QPA_PLATFORM: offscreen
47+
QT_QUICK_BACKEND: software
48+
run: build/release/bin/monero-wallet-gui --test-qml
4849

4950
build-windows:
51+
if: false
5052
runs-on: windows-latest
5153
defaults:
5254
run:
@@ -60,19 +62,21 @@ jobs:
6062
msystem: ucrt64
6163
update: true
6264
install: make
63-
pacboy: toolchain:p ccache:p pcre:p cmake:p boost:p openssl:p zeromq:p libsodium:p hidapi:p protobuf:p libusb:p unbound:p git qt6-base:p qt6-declarative:p qt6-svg:p qt6-tools:p qt6-imageformats:p libgcrypt:p
65+
pacboy: toolchain:p ccache:p pcre:p cmake:p boost:p openssl:p zeromq:p libsodium:p hidapi:p protobuf:p libusb:p unbound:p git qt6-base:p qt6-declarative:p qt6-svg:p qt6-tools:p libgcrypt:p
6466
- name: add qmlimportscanner.exe
6567
run: cp -f "$MSYSTEM_PREFIX/share/qt6/bin/qmlimportscanner.exe" "$MSYSTEM_PREFIX/bin/qmlimportscanner.exe"
6668
- name: configure
6769
run: cmake -S . -B build/ci -G "MSYS Makefiles" -DDEV_MODE=ON -DWITH_SCANNER=OFF -DARCH=x86-64 -DBUILD_64=ON -DBUILD_TAG=win-x64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
6870
- name: build
69-
run: cmake --build build/ci --target monero-wallet-gui -j8
71+
run: DEV_MODE=ON make release-win64 -j4
7072
- name: deploy
71-
run: cmake --build build/ci --target deploy -j8
73+
run: make deploy
74+
working-directory: build/release
7275
- name: test qml
73-
run: build/ci/bin/monero-wallet-gui --test-qml
76+
run: build/release/bin/monero-wallet-gui --test-qml
7477

7578
macos-bundle:
79+
if: false
7680
name: macOS ${{ matrix.arch }} bundle
7781
runs-on: ${{ matrix.runner }}
7882
strategy:
@@ -87,8 +91,6 @@ jobs:
8791
artifact_name: macos-x64-bundle
8892
archive_name: monero-wallet-gui-macos-x64.tar.gz
8993
arch: Intel
90-
env:
91-
MACOSX_DEPLOYMENT_TARGET: "12.0"
9294
steps:
9395
- uses: actions/checkout@v7
9496
with:
@@ -100,54 +102,51 @@ jobs:
100102
working-directory: ../
101103
- name: configure
102104
run: >
103-
cmake -S . -B build/bundle -G Ninja
104-
-DDEV_MODE=ON
105-
-DWITH_SCANNER=OFF
106-
-DCMAKE_BUILD_TYPE=Release
107-
-DCMAKE_PREFIX_PATH="/Users/runner/work/monero-gui/qt6.8.3/"
108-
-DCMAKE_OSX_DEPLOYMENT_TARGET="${MACOSX_DEPLOYMENT_TARGET}"
105+
cmake -S . -B build -G Ninja
106+
-D CMAKE_BUILD_TYPE=Release
107+
-D CMAKE_PREFIX_PATH="/Users/runner/work/monero-gui/qt6.8.3/"
108+
-D CMAKE_OSX_DEPLOYMENT_TARGET="12.0"
109+
-D ARCH=default
109110
- name: build
110-
run: cmake --build build/bundle --target monero-wallet-gui --parallel 8
111+
run: cmake --build build
111112
- name: deploy
112-
run: cmake --build build/bundle --target deploy
113+
run: cmake --build build --target deploy
113114
- name: test qml
114-
run: build/bundle/bin/monero-wallet-gui.app/Contents/MacOS/monero-wallet-gui --test-qml
115+
run: build/bin/monero-wallet-gui.app/Contents/MacOS/monero-wallet-gui --test-qml
115116
- name: create archive
116-
run: tar -C build/bundle/bin -czf "${{ matrix.archive_name }}" monero-wallet-gui.app
117+
run: tar -C build/bin -czf "${{ matrix.archive_name }}" monero-wallet-gui.app
117118
- uses: actions/upload-artifact@v7.0.1
118119
with:
119120
name: ${{ matrix.artifact_name }}
120121
path: ${{ matrix.archive_name }}
121122
archive: false
122123

123124
docker-linux-static:
125+
if: false
124126
runs-on: ubuntu-22.04
125127
steps:
126128
- uses: actions/checkout@v1
127129
with:
128130
submodules: recursive
129-
- name: install dependencies
130-
run: sudo apt -y install libopengl0 libglx0 libgl1
131131
- name: free up diskspace
132132
run: ${{env.FREE_DISKSPACE}}
133133
- name: prepare build environment
134-
run: docker build --tag monero:build-env-linux --build-arg THREADS=3 --file Dockerfile.linux .
134+
run: docker build --tag monero:build-env-linux --build-arg THREADS=4 --file Dockerfile.linux .
135135
- name: build
136-
run: docker run --rm -v /home/runner/work/monero-gui/monero-gui:/monero-gui -w /monero-gui monero:build-env-linux sh -c 'make release-static -j3'
136+
run: docker run --rm -v /home/runner/work/monero-gui/monero-gui:/monero-gui -w /monero-gui monero:build-env-linux sh -c 'make depends root=/depends target=x86_64-linux-gnu tag=linux-x64 -j4'
137137
- name: sha256sum
138-
run: shasum -a256 /home/runner/work/monero-gui/monero-gui/build/release/bin/monero-wallet-gui
138+
run: shasum -a256 /home/runner/work/monero-gui/monero-gui/build/x86_64-linux-gnu/release/bin/monero-wallet-gui
139139
- name: test qml
140140
env:
141141
QT_QPA_PLATFORM: offscreen
142-
QT_QUICK_BACKEND: opengl
143-
LIBGL_ALWAYS_SOFTWARE: "1"
144-
run: /home/runner/work/monero-gui/monero-gui/build/release/bin/monero-wallet-gui --test-qml
142+
QT_QUICK_BACKEND: software
143+
run: /home/runner/work/monero-gui/monero-gui/build/x86_64-linux-gnu/release/bin/monero-wallet-gui --test-qml
145144
- uses: actions/upload-artifact@v4
146145
with:
147146
name: ${{ github.job }}
148147
path: |
149-
/home/runner/work/monero-gui/monero-gui/build/release/bin/monero-wallet-gui
150-
/home/runner/work/monero-gui/monero-gui/build/release/bin/monerod
148+
/home/runner/work/monero-gui/monero-gui/build/x86_64-linux-gnu/release/bin/monero-wallet-gui
149+
/home/runner/work/monero-gui/monero-gui/build/x86_64-linux-gnu/release/bin/monerod
151150
152151
docker-windows-static:
153152
runs-on: ubuntu-22.04
@@ -158,9 +157,9 @@ jobs:
158157
- name: free up disk space
159158
run: ${{ env.FREE_DISKSPACE }}
160159
- name: prepare build environment
161-
run: docker build --tag monero:build-env-windows --build-arg THREADS=3 --file Dockerfile.windows .
160+
run: docker build --tag monero:build-env-windows --build-arg THREADS=4 --file Dockerfile.windows .
162161
- name: build
163-
run: docker run --rm -v /home/runner/work/monero-gui/monero-gui:/monero-gui -w /monero-gui monero:build-env-windows sh -c 'make depends root=/depends target=x86_64-w64-mingw32 tag=win-x64 -j3'
162+
run: docker run --rm -v /home/runner/work/monero-gui/monero-gui:/monero-gui -w /monero-gui monero:build-env-windows sh -c 'make depends root=/depends target=x86_64-w64-mingw32 tag=win-x64 -j4'
164163
- name: sha256sum
165164
run: shasum -a256 /home/runner/work/monero-gui/monero-gui/build/x86_64-w64-mingw32/release/bin/monero-wallet-gui.exe
166165
- uses: actions/upload-artifact@v4
@@ -179,9 +178,9 @@ jobs:
179178
- name: free up diskspace
180179
run: ${{env.FREE_DISKSPACE}}
181180
- name: prepare build environment
182-
run: docker build --tag monero:build-env-android --build-arg THREADS=3 --file Dockerfile.android .
181+
run: docker build --tag monero:build-env-android --build-arg THREADS=4 --file Dockerfile.android .
183182
- name: build
184-
run: docker run --rm -v /home/runner/work/monero-gui/monero-gui:/monero-gui -e THREADS=3 monero:build-env-android
183+
run: docker run --rm -v /home/runner/work/monero-gui/monero-gui:/monero-gui -e THREADS=4 monero:build-env-android
185184
- uses: actions/upload-artifact@v4
186185
with:
187186
name: ${{ github.job }}

Dockerfile.android

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ ARG ANDROID_SDK_REVISION=11076708_latest
77
ARG ANDROID_SDK_HASH=2d2d50857e4eb553af5a6dc3ad507a17adf43d115264b1afc116f95c92e5e258
88
ARG QT_VERSION=v6.8.3
99
ARG QT_COMMIT=bab1fecd556ea561c4a89686293116741acfa1b4
10+
ARG QT_HOST_VERSION=6.8.3
11+
ARG QT_HOST_SHA256=8bbea76f5298021048f54c3e2934d7a73e2e6498ebc5a0cb30de16e24a66d847
1012

1113
WORKDIR /opt/android
1214
ENV WORKDIR=/opt/android
@@ -18,15 +20,17 @@ ENV ANDROID_CLANGPP=aarch64-linux-android${ANDROID_NATIVE_API_LEVEL}-clang++
1820
ENV ANDROID_NDK_ROOT=${WORKDIR}/android-ndk-r${ANDROID_NDK_REVISION}
1921
ENV ANDROID_SDK_ROOT=${WORKDIR}/cmdline-tools
2022
ENV JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
21-
ENV PATH=${JAVA_HOME}/bin:${PATH}
23+
ENV PATH=${WORKDIR}/qt-host/bin:${WORKDIR}/qt-host/libexec:${JAVA_HOME}/bin:${PATH}
2224
ENV PREFIX=${WORKDIR}/prefix
2325
ENV QT_HOST_PREFIX=${WORKDIR}/qt-host
26+
ENV LD_LIBRARY_PATH=${QT_HOST_PREFIX}/lib
2427
ENV TOOLCHAIN_DIR=${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/linux-x86_64
2528
ENV DEBIAN_FRONTEND=noninteractive
2629

2730
RUN apt-get update \
28-
&& apt-get install -y ant automake build-essential ca-certificates-java file gettext git libc6 libncurses5 \
29-
libssl-dev libstdc++6 libtinfo5 libtool libz1 ninja-build openjdk-17-jdk-headless \
31+
&& apt-get install -y ant aria2 automake build-essential ca-certificates-java file gettext git libc6 libncurses5 \
32+
libdbus-1-3 libegl1 libfontconfig1 libfreetype6 libgl1 libglib2.0-0 libgssapi-krb5-2 libssl-dev \
33+
libstdc++6 libtinfo5 libtool libx11-6 libxkbcommon0 libz1 libzstd1 libarchive-tools ninja-build openjdk-17-jdk-headless \
3034
openjdk-17-jre-headless pkg-config python3 unzip wget \
3135
&& rm -rf /var/lib/apt/lists/*
3236

@@ -59,6 +63,25 @@ RUN git clone -b v4.3.3 --depth 1 https://github.com/Kitware/CMake \
5963
ENV HOST_PATH=${PATH}
6064
ENV PATH=${TOOLCHAIN_DIR}/aarch64-linux-android/bin:${TOOLCHAIN_DIR}/bin:${PATH}
6165

66+
COPY .github/qt_helper.py /tmp/qt_helper.py
67+
68+
RUN mkdir -p "${QT_HOST_PREFIX}" \
69+
&& cd "${QT_HOST_PREFIX}" \
70+
&& python3 /tmp/qt_helper.py linux_x64 desktop "${QT_HOST_VERSION}" linux_gcc_64 "${QT_HOST_SHA256}" \
71+
--add-package addons.qtshadertools \
72+
--archive 'qtbase-*.7z' \
73+
--archive 'qtdeclarative-*.7z' \
74+
--archive 'qttools-*.7z' \
75+
--archive 'icu-*.7z' \
76+
--archive 'qtshadertools-*.7z' \
77+
&& find "${QT_HOST_PREFIX}" -name 'libicu*.so*' -print \ # TODEL
78+
&& rm /tmp/qt_helper.py \
79+
&& echo "${QT_HOST_PREFIX}/lib" > /etc/ld.so.conf.d/qt-host.conf \
80+
&& ldconfig \
81+
&& ldd "${QT_HOST_PREFIX}/libexec/qvkgen" | tee /tmp/qvkgen.ldd \
82+
&& ! grep -q 'not found' /tmp/qvkgen.ldd \
83+
&& rm /tmp/qvkgen.ldd
84+
6285
ARG ZLIB_VERSION=1.3.1
6386
ARG ZLIB_HASH=9a93b2b7dfdac77ceba5a558a580e74667dd6fede4585b91eefb60f03b72df23
6487
RUN wget -q https://github.com/madler/zlib/releases/download/v${ZLIB_VERSION}/zlib-${ZLIB_VERSION}.tar.gz \
@@ -73,25 +96,10 @@ RUN wget -q https://github.com/madler/zlib/releases/download/v${ZLIB_VERSION}/zl
7396

7497
RUN git clone https://code.qt.io/qt/qt5.git -b ${QT_VERSION} --depth 1 qt-sources \
7598
&& git -C qt-sources reset --hard ${QT_COMMIT} \
76-
&& mkdir qt-build-host \
77-
&& cd qt-build-host \
78-
&& ../qt-sources/configure -init-submodules \
79-
-submodules qtbase,qtdeclarative,qtimageformats,qtmultimedia,qtshadertools,qtsvg,qttools \
80-
-prefix ${QT_HOST_PREFIX} \
81-
-opensource -confirm-license -release \
82-
-no-opengl -no-dbus -no-sql-sqlite \
83-
-no-feature-assistant -no-feature-designer \
84-
-no-feature-distancefieldgenerator -no-feature-pixeltool \
85-
-no-feature-qtattributionsscanner -no-feature-qtdiag \
86-
-no-feature-qtplugininfo \
87-
-nomake examples -nomake tests \
88-
&& cmake --build . --parallel ${THREADS} \
89-
&& cmake --install . \
90-
&& cd .. \
9199
&& mkdir qt-build-android \
92100
&& cd qt-build-android \
93-
&& PATH=${HOST_PATH} ../qt-sources/configure \
94-
-submodules qtbase,qtdeclarative,qtimageformats,qtmultimedia,qtshadertools,qtsvg,qttools \
101+
&& PATH=${HOST_PATH} ../qt-sources/configure -init-submodules \
102+
-submodules qtbase,qtdeclarative,qtshadertools,qtsvg,qttools \
95103
-prefix ${PREFIX} \
96104
-qt-host-path ${QT_HOST_PREFIX} \
97105
-android-ndk ${ANDROID_NDK_ROOT} \
@@ -109,7 +117,7 @@ RUN git clone https://code.qt.io/qt/qt5.git -b ${QT_VERSION} --depth 1 qt-source
109117
&& PATH=${HOST_PATH} cmake --build . --parallel ${THREADS} \
110118
&& PATH=${HOST_PATH} cmake --install . \
111119
&& cd .. \
112-
&& rm -rf qt-build-host qt-build-android qt-sources
120+
&& rm -rf qt-build-android qt-sources
113121

114122
ARG ICONV_VERSION=1.18
115123
ARG ICONV_HASH=3b08f5f4f9b4eb82f151a7040bfd6fe6c6fb922efe4b1659c66ea933276965e8

0 commit comments

Comments
 (0)