fix failed CI builds

This commit is contained in:
2026-09-10 19:55:33 -06:00
parent 8bf2caf20d
commit 6f5e3b395f
8 changed files with 116 additions and 18 deletions

View File

@@ -30,7 +30,7 @@ jobs:
gettext \
libcanberra-dev libglib2.0-dev \
libarchive-dev \
libgtk-3-dev libfontconfig1-dev libpango1.0-dev xvfb xauth \
libgtk-3-dev libfontconfig1-dev libpango1.0-dev xvfb xauth dbus-daemon at-spi2-core \
libwayland-client0 libwayland-cursor0 libwayland-egl1 \
libxkbcommon0 \
libgtk-3-bin libglib2.0-bin shared-mime-info gsettings-desktop-schemas \
@@ -57,7 +57,7 @@ jobs:
ninja -C build
- name: Test emoji catalog, font coverage and picker
run: xvfb-run -a meson test -C build --print-errorlogs "Emoji Data Tests" "Emoji Font Tests" "Emoji UI Tests"
run: xvfb-run -a dbus-run-session -- meson test -C build --print-errorlogs "Emoji Data Tests" "Emoji Font Tests" "Emoji UI Tests"
- name: Install to AppDir
run: |

View File

@@ -69,6 +69,30 @@ jobs:
Download-WithRetry -Url https://github.com/ZoiteChat/gvsbuild/releases/download/zoitechat-2.20.0-alpha.1/GTK3_Gvsbuild_zoitechat-2.20.0-alpha.1_x64.zip -OutFile deps\gtk-${{ matrix.arch }}.zip
Expand-Archive -LiteralPath deps\gtk-${{ matrix.arch }}.zip -DestinationPath C:\gtk-build\gtk\x64\release -Force
# The GTK3 archive omits librsvg. Add only its renderer, loader and
# license from the companion release, keeping the GTK3 DLLs intact.
Download-WithRetry -Url https://github.com/ZoiteChat/gvsbuild/releases/download/zoitechat-2.20.0-alpha.1/GTK4_Gvsbuild_zoitechat-2.20.0-alpha.1_x64.zip -OutFile deps\svg-runtime.zip
if ((Get-FileHash deps\svg-runtime.zip -Algorithm SHA256).Hash -ne 'fb657f9ebae3a6807defb15e66091d643a703ee66cb37488e3e11e5646f45adb') {
throw 'Unexpected SVG runtime archive checksum'
}
$svgArchive = [System.IO.Compression.ZipFile]::OpenRead((Resolve-Path deps\svg-runtime.zip))
try {
foreach ($name in @('bin/rsvg-2-2.dll', 'lib/gdk-pixbuf-2.0/2.10.0/loaders/pixbufloader_svg.dll', 'share/doc/librsvg/COPYING.LIB')) {
$entry = $svgArchive.GetEntry($name)
if ($null -eq $entry) { throw "Missing SVG runtime file: $name" }
$destination = Join-Path 'C:\gtk-build\gtk\x64\release' $name
New-Item -ItemType Directory -Path (Split-Path $destination) -Force | Out-Null
[System.IO.Compression.ZipFileExtensions]::ExtractToFile($entry, $destination, $true)
}
}
finally { $svgArchive.Dispose() }
# This loads the module now, catching missing DLLs before the build.
& C:\gtk-build\gtk\x64\release\bin\gdk-pixbuf-query-loaders.exe --update-cache
if ($LASTEXITCODE -ne 0) { throw 'Could not generate the pixbuf loader cache' }
if (-not (Select-String -LiteralPath 'C:\gtk-build\gtk\x64\release\lib\gdk-pixbuf-2.0\2.10.0\loaders.cache' -SimpleMatch '"svg"')) {
throw 'SVG loader could not be loaded with the GTK3 runtime'
}
Download-WithRetry -Url https://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-hicolor-icon-theme-0.18-1-any.pkg.tar.zst -OutFile deps\hicolor-icon-theme.pkg.tar.zst
python -c "import tarfile,zstandard,pathlib;archive=pathlib.Path(r'deps\\hicolor-icon-theme.pkg.tar.zst');target=pathlib.Path(r'C:\\gtk-build\\gtk\\x64\\release');dctx=zstandard.ZstdDecompressor();f=archive.open('rb');reader=dctx.stream_reader(f);tf=tarfile.open(fileobj=reader,mode='r|');[tf.extract(m,path=target) for m in tf if m.name.startswith('mingw64/share/icons/hicolor/')];tf.close();reader.close();f.close()"
@@ -179,6 +203,7 @@ jobs:
run: |
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\VsDevCmd.bat"
set "PATH=%CD%\..\zoitechat-build\x64\rel;%PATH%"
set "GDK_PIXBUF_MODULE_FILE=%CD%\..\zoitechat-build\x64\rel\lib\gdk-pixbuf-2.0\2.10.0\loaders.cache"
set "ZOITECHAT_EMOJI_FONT=%CD%\..\zoitechat-build\x64\rel\share\fonts\zoitechat\NotoColorEmoji.ttf"
fc /b data\fonts\NotoColorEmoji.ttf "%ZOITECHAT_EMOJI_FONT%"
if errorlevel 1 exit /b 1

View File

@@ -78,7 +78,9 @@ emoji_font_get_map (void)
"<edit name='family' mode='assign'><string>" ZOITECHAT_EMOJI_FAMILY
"</string></edit></match>"
"<match target='pattern'><test name='family'><string>emoji</string></test>"
"<edit name='family' mode='prepend' binding='strong'><string>"
/* System rules may already have prepended older emoji families.
* Put our bundled family before those, not just before 'emoji'. */
"<edit name='family' mode='prepend_first' binding='strong'><string>"
ZOITECHAT_EMOJI_FAMILY "</string></edit></match>"
"</fontconfig>", escaped);
registered = FcConfigParseAndLoadFromMemory (config, (const FcChar8 *) rules, FcTrue) &&

View File

@@ -3,6 +3,52 @@
#include "../emoji-font.h"
#include "../../common/emoji-data.h"
#include <pango/pangofc-fontmap.h>
#include <pango/pangofc-font.h>
static GHashTable *font_checksums;
static char *bundled_checksum;
static const char *
font_checksum (const char *path)
{
const char *cached = g_hash_table_lookup (font_checksums, path);
char *contents, *checksum;
gsize length;
if (cached)
return cached;
g_assert_true (g_file_get_contents (path, &contents, &length, NULL));
checksum = g_compute_checksum_for_data (G_CHECKSUM_SHA256,
(const guchar *) contents, length);
g_free (contents);
g_hash_table_insert (font_checksums, g_strdup (path), checksum);
return checksum;
}
static void
assert_bundled_font (PangoFont *font, gboolean expected)
{
FcPattern *pattern;
FcChar8 *path;
const char *checksum;
/* Pango can describe a face by its embedded name rather than its
* Fontconfig alias. Verify the resolved file's bytes, not that name.
* Cache by filename so catalog coverage does not reread the font for
* every glyph. An older system Noto must still fail this assertion. */
g_assert_true (PANGO_IS_FC_FONT (font));
#if PANGO_VERSION_CHECK(1, 48, 0)
pattern = pango_fc_font_get_pattern (PANGO_FC_FONT (font));
#else
pattern = PANGO_FC_FONT (font)->font_pattern;
#endif
g_assert_cmpint (FcPatternGetString (pattern, FC_FILE, 0, &path), ==, FcResultMatch);
checksum = font_checksum ((const char *) path);
if (expected)
g_assert_cmpstr (checksum, ==, bundled_checksum);
else
g_assert_cmpstr (checksum, !=, bundled_checksum);
}
static void
test_font_catalog (void)
@@ -34,9 +80,7 @@ test_font_catalog (void)
PangoLayoutRun *run = pango_layout_iter_get_run_readonly (iter);
if (run)
{
PangoFontDescription *actual = pango_font_describe (run->item->analysis.font);
g_assert_cmpstr (pango_font_description_get_family (actual), ==, ZOITECHAT_EMOJI_FAMILY);
pango_font_description_free (actual);
assert_bundled_font (run->item->analysis.font, TRUE);
}
} while (pango_layout_iter_next_run (iter));
pango_layout_iter_free (iter);
@@ -68,9 +112,7 @@ test_plain_text_font (void)
PangoLayoutRun *run = pango_layout_iter_get_run_readonly (iter);
if (run)
{
PangoFontDescription *actual = pango_font_describe (run->item->analysis.font);
g_assert_cmpstr (pango_font_description_get_family (actual), !=, ZOITECHAT_EMOJI_FAMILY);
pango_font_description_free (actual);
assert_bundled_font (run->item->analysis.font, FALSE);
}
} while (pango_layout_iter_next_run (iter));
pango_layout_iter_free (iter);
@@ -101,9 +143,7 @@ test_implicit_emoji_font (void)
PangoLayoutRun *run = pango_layout_iter_get_run_readonly (iter);
if (run)
{
PangoFontDescription *actual = pango_font_describe (run->item->analysis.font);
g_assert_cmpstr (pango_font_description_get_family (actual), ==, ZOITECHAT_EMOJI_FAMILY);
pango_font_description_free (actual);
assert_bundled_font (run->item->analysis.font, TRUE);
}
} while (pango_layout_iter_next_run (iter));
pango_layout_iter_free (iter);
@@ -116,9 +156,19 @@ test_implicit_emoji_font (void)
int
main (int argc, char **argv)
{
const char *path;
int result;
g_test_init (&argc, &argv, NULL);
path = g_getenv ("ZOITECHAT_EMOJI_FONT");
g_assert_nonnull (path);
font_checksums = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
bundled_checksum = g_strdup (font_checksum (path));
g_test_add_func ("/emoji-font/catalog", test_font_catalog);
g_test_add_func ("/emoji-font/plain-text", test_plain_text_font);
g_test_add_func ("/emoji-font/implicit-emoji", test_implicit_emoji_font);
return g_test_run ();
result = g_test_run ();
g_free (bundled_checksum);
g_hash_table_destroy (font_checksums);
return result;
}

View File

@@ -12,6 +12,22 @@
struct zoitechatprefs prefs;
static char *config_dir;
static void
test_theme_svg_loader (void)
{
GError *error = NULL;
GdkPixbuf *pixbuf;
/* Exercise the theme asset that failed in the packaged Windows runtime. */
pixbuf = gdk_pixbuf_new_from_resource (
"/org/gtk/libgtk/theme/Adwaita/assets/bullet-symbolic.svg", &error);
g_assert_no_error (error);
g_assert_nonnull (pixbuf);
g_assert_cmpint (gdk_pixbuf_get_width (pixbuf), >, 0);
g_assert_cmpint (gdk_pixbuf_get_height (pixbuf), >, 0);
g_object_unref (pixbuf);
}
char *get_xdir (void) { return config_dir; }
PreferencesPersistenceResult preferences_persistence_save_all (void)
{
@@ -125,6 +141,7 @@ main (int argc, char **argv)
g_object_set (gtk_settings_get_default (), "gtk-enable-animations", FALSE, NULL);
config_dir = g_dir_make_tmp ("zoitechat-emoji-tests-XXXXXX", NULL);
g_assert_nonnull (config_dir);
g_test_add_func ("/emoji-ui/theme-svg-loader", test_theme_svg_loader);
g_test_add ("/emoji-ui/search-insertion", PickerFixture, NULL, fixture_setup, test_search_insertion, fixture_teardown);
g_test_add ("/emoji-ui/read-only", PickerFixture, NULL, fixture_setup, test_read_only, fixture_teardown);
g_test_add ("/emoji-ui/sequence-limit", PickerFixture, NULL, fixture_setup, test_sequence_limit, fixture_teardown);

View File

@@ -37,6 +37,7 @@
<None Include="$(DepsRoot)\bin\*fribidi*.dll" />
<None Include="$(DepsRoot)\bin\*fontconfig*.dll" />
<None Include="$(DepsRoot)\bin\*gdk_pixbuf*.dll" />
<None Include="$(DepsRoot)\bin\rsvg-2-2.dll" />
<None Include="$(DepsRoot)\bin\*gdk-3*.dll" />
<None Include="$(DepsRoot)\bin\*epoxy*.dll" />
<None Include="$(DepsRoot)\bin\*gio-2*.dll" />
@@ -78,8 +79,8 @@
<Gtk3Immodules Include="$(DepsRoot)\lib\gtk-3.0\3.0.0\immodules\**\*" />
<Gtk3PrintBackends Include="$(DepsRoot)\lib\gtk-3.0\3.0.0\printbackends\**\*" />
<GSettingsSchemas Include="$(DepsRoot)\share\glib-2.0\schemas\*" />
<GdkPixbufLoaders Include="$(DepsRoot)\lib\gdk-pixbuf-2.0\**\loaders\**\*" />
<GdkPixbufLoaderCache Include="$(DepsRoot)\lib\gdk-pixbuf-2.0\**\loaders.cache" />
<!-- Preserve the version/loaders directories used by the relative cache. -->
<GdkPixbufRuntime Include="$(DepsRoot)\lib\gdk-pixbuf-2.0\**\*" />
<FontConfig Include="$(DepsRoot)\etc\fonts\**\*" />
<EmojiFont Include="..\..\data\fonts\NotoColorEmoji.ttf" />
@@ -97,8 +98,8 @@
<Copy SourceFiles="@(EmojiFontLicense)" DestinationFolder="$(ZoiteChatRel)\share\doc\zoitechat\fonts" />
<Copy SourceFiles="@(Gtk3Immodules)" DestinationFiles="@(Gtk3Immodules->'$(ZoiteChatRel)\lib\gtk-3.0\3.0.0\immodules\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="@(Gtk3PrintBackends)" DestinationFiles="@(Gtk3PrintBackends->'$(ZoiteChatRel)\lib\gtk-3.0\3.0.0\printbackends\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="@(GdkPixbufLoaders)" DestinationFiles="@(GdkPixbufLoaders->'$(ZoiteChatRel)\lib\gdk-pixbuf-2.0\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="@(GdkPixbufLoaderCache)" DestinationFiles="@(GdkPixbufLoaderCache->'$(ZoiteChatRel)\lib\gdk-pixbuf-2.0\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="@(GdkPixbufRuntime)" DestinationFiles="@(GdkPixbufRuntime->'$(ZoiteChatRel)\lib\gdk-pixbuf-2.0\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="$(DepsRoot)\share\doc\librsvg\COPYING.LIB" DestinationFolder="$(ZoiteChatRel)\share\doc\librsvg" />
<Copy SourceFiles="@(GSettingsSchemas)" DestinationFiles="@(GSettingsSchemas->'$(ZoiteChatRel)\share\glib-2.0\schemas\%(Filename)%(Extension)')" />
<Copy SourceFiles="@(Share)" DestinationFiles="@(Share->'$(ZoiteChatRel)\share\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="..\..\COPYING" DestinationFolder="$(ZoiteChatRel)\share\doc\zoitechat" />

View File

@@ -106,6 +106,8 @@ Source: "share\xml\*"; DestDir: "{app}\share\xml"; Flags: ignoreversion createal
Source: "share\doc\zoitechat\*"; DestDir: "{app}\share\doc\zoitechat"; Flags: ignoreversion createallsubdirs recursesubdirs; Components: libs
Source: "share\fonts\zoitechat\*"; DestDir: "{app}\share\fonts\zoitechat"; Flags: ignoreversion createallsubdirs recursesubdirs; Components: libs
Source: "share\doc\WinSparkle\*"; DestDir: "{app}\share\doc\WinSparkle"; Flags: ignoreversion createallsubdirs recursesubdirs; Components: libs
Source: "share\doc\librsvg\*"; DestDir: "{app}\share\doc\librsvg"; Flags: ignoreversion createallsubdirs recursesubdirs; Components: libs
Source: "lib\gdk-pixbuf-2.0\*"; DestDir: "{app}\lib\gdk-pixbuf-2.0"; Flags: ignoreversion createallsubdirs recursesubdirs; Components: libs
Source: "share\themes\MS-Windows\*"; DestDir: "{app}\share\themes\MS-Windows"; Flags: ignoreversion createallsubdirs recursesubdirs skipifsourcedoesntexist; Components: libs
Source: "share\glib-2.0\schemas\*"; DestDir: "{app}\share\glib-2.0\schemas"; Flags: ignoreversion createallsubdirs recursesubdirs skipifsourcedoesntexist; Components: libs
Source: "share\icons\hicolor\*"; DestDir: "{app}\share\icons\hicolor"; Flags: ignoreversion createallsubdirs recursesubdirs skipifsourcedoesntexist; Components: libs
@@ -118,6 +120,7 @@ Source: "freetype-6.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: li
Source: "fribidi-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "fontconfig-1.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "gdk_pixbuf-2.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "rsvg-2-2.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "gdk-3-vs17.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "epoxy-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "gio-2.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs

View File

@@ -75,7 +75,7 @@
<UsingGtk3 Condition="Exists('$(DepsRoot)\\include\\gtk-3.0\\gtk\\gtk.h')">true</UsingGtk3>
<Gtk3>$(DepsRoot)\include\gtk-3.0;$(DepsRoot)\lib\gtk-3.0\include</Gtk3>
<GtkCommon>$(DepsRoot)\include\atk-1.0;$(DepsRoot)\include\cairo;$(DepsRoot)\include\pango-1.0;$(DepsRoot)\include\gdk-pixbuf-2.0;$(DepsRoot)\include\harfbuzz</GtkCommon>
<GtkCommon>$(DepsRoot)\include\atk-1.0;$(DepsRoot)\include\cairo;$(DepsRoot)\include\pango-1.0;$(DepsRoot)\include\gdk-pixbuf-2.0;$(DepsRoot)\include\harfbuzz;$(DepsRoot)\include\freetype2</GtkCommon>
<Gtk>$(Gtk3);$(GtkCommon)</Gtk>
<SslLegacyLib Condition="Exists('$(DepsRoot)\\lib\\ssleay32.lib')">ssleay32.lib</SslLegacyLib>