Skip to content

Подпись кода через SignPath Foundation: Windows-сборки на GitHub Actions - #4

Merged
Mercurrial merged 3 commits into
mainfrom
claude/determined-hypatia-tw8a26
Oct 26, 2026
Merged

Mercurrial merged 3 commits into
mainfrom
claude/determined-hypatia-tw8a26

Conversation

@Mercurrial

@Mercurrial Mercurrial commented Oct 26, 2026 •

Copy link
Copy Markdown
Owner

Что изменено и зачем

Подготовка к бесплатной подписи кода через SignPath Foundation, чтобы Windows SmartScreen перестал показывать предупреждение о неизвестном издателе. SignPath подписывает только файлы, собранные GitHub Actions из этого репозитория, поэтому файлы выпуска для Windows теперь собираются там, а не локально.

  • .github/workflows/build.yml, новое задание windows:

    • тесты на Windows;
    • сборка программ (build_installer.py --portable --only programs);
    • запрос на подпись программ в SignPath;
    • сборка установщика уже из подписанных файлов (--only installer);
    • тихая установка «только для меня» и проверка, что программа работает через 20 с;
    • запрос на подпись установщика;
    • проверка подписей.

    Подпись включается переменной репозитория SIGNPATH_ORGANIZATION_ID. Без неё задание собирает те же файлы без подписи.

  • tools/build_installer.py: опция --only programs|installer, чтобы между этапами подписать файлы. По умолчанию всё работает как раньше.

  • tools/release.py: в выпуск загружаются Windows-файлы из сборки GitHub Actions (dist/ci/windows/…). Тест обновлён.

  • installer/signpath/: две конфигурации артефактов для SignPath (programs.xml, installer.xml) и пошаговая инструкция: заявка, настройка SignPath и GitHub, пробный запуск, выпуск версии.

  • docs/code-signing.md (+ .en.md): политика подписи кода, которую SignPath требует на сайте проекта. В ней — что подписывается, роли, как проверить подпись, конфиденциальность (единственный сетевой запрос, который программа делает сама, — проверка обновлений). Страница добавлена в меню «Помощь», ссылки на неё — в README, SECURITY.md и CHANGELOG.

  • ARCHITECTURE.md и engineering-notes: описание новой сборки и причины решений.

  • Отдельный коммит fix(update): updater.start_detached передавал Windows-флаг creationflags и на Linux/macOS, где Popen отвечает на него ValueError. Из-за этого с 3af3ad5 на main падали 4 теста фоновой установки.

Тексты про SmartScreen в README, установке и решении проблем не менялись: они остаются верными, пока не вышел первый подписанный выпуск (см. раздел 6 инструкции).

Как проверено

  • python -m pytest проходит полностью (с исправлением start_detached)
  • тест скрипта выпуска обновлён: проверяет, что в выпуск загружаются файлы из сборки GitHub Actions
  • mkdocs build --strict проходит, страница code-signing собирается на обоих языках
  • задание windows проверено запуском build на этой ветке (run 40310343939): тесты на Windows, сборка, установка, запуск через 20 с и артефакт windows прошли; шаги подписи пропущены, пока SignPath не подключён
  • заметное для пользователя изменение описано в разделе «Не выпущено» в CHANGELOG.md

🤖 Generated with Claude Code

https://claude.ai/code/session_01Xm2TjWChGFxTMcXbxuvAaQ

Copy link
Copy Markdown
Owner Author

Проверка tests / ubuntu-latest красная, но не из-за этого PR. На main она красная начиная с 3af3ad5 (feat(update): updates install in the background). Падают те же 4 теста:

  • test_side_by_side.py::test_a_background_update_ends_with_the_rail_button
  • test_side_by_side.py::test_a_failed_background_install_says_so
  • test_side_by_side.py::test_the_card_installs_and_turns_into_restart
  • test_updater.py::test_an_automatic_offer_waits_for_the_first_launch_guide

Причина. core/updater.py → start_detached() передаёт в subprocess.Popen аргумент creationflags. На Linux и macOS Popen отвечает на него ValueError: creationflags is only supported on Windows platforms. Блок except OSError эту ошибку не ловит, поэтому фоновая установка в тестах так и не стартует. В рабочей программе это не проявляется: сборки для Linux и macOS обновляются через страницу выпуска и start_detached не вызывают.

Готового исправления пока нет. Предлагаю такой патч (проверил локально: весь набор тестов проходит):

     kw = dict(stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL,
               stderr=subprocess.DEVNULL, close_fds=True, env=child_env())
+    if sys.platform != "win32":
+        # creationflags is Windows-only (Popen raises ValueError elsewhere).
+        return subprocess.Popen(args, start_new_session=True, **kw)
     try:
         return subprocess.Popen(args, creationflags=flags | 0x01000000, **kw)

В этот PR патч не добавляю, чтобы не смешивать задачи. Если нужно, оформлю его отдельным коммитом здесь или отдельным PR.


Generated by Claude Code

@Mercurrial
Mercurrial force-pushed the claude/determined-hypatia-tw8a26 branch from b928684 to 6bf2b48 Compare October 26, 2026 10:58
On Linux and macOS subprocess.Popen refuses creationflags with a
ValueError, which the OSError fallback did not catch: the background
install never started there and four tests failed on the Linux runner
since 3af3ad5. Elsewhere the child now gets its own session instead.
The builds for those systems update through the release page and never
call it; only the tests do.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xm2TjWChGFxTMcXbxuvAaQ
…h SignPath

SignPath Foundation signs only artifacts built by a GitHub Actions run of
this repository, so the Windows files of a release now come from the build
workflow instead of a local build:

- build.yml, job "windows": the tests, the programs
  (build_installer.py --portable --only programs), a signing request for
  them, the installer from the signed files (--only installer), a silent
  per-user install and a 20-second start check, a signing request for the
  installer, a signature check. Signing is on while the repository has the
  variable SIGNPATH_ORGANIZATION_ID; without it the same files are built
  unsigned.
- installer/signpath/: the two artifact configurations and the set-up and
  release steps.
- release.py uploads the CI-built Windows files.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xm2TjWChGFxTMcXbxuvAaQ
The page SignPath requires on the project site: attribution, what is
signed, how a signed file is made, team roles, how to check a signature
and the privacy statement (the update check is the only traffic the app
starts by itself). Linked from the README, SECURITY.md and the changelog.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xm2TjWChGFxTMcXbxuvAaQ
@Mercurrial
Mercurrial force-pushed the claude/determined-hypatia-tw8a26 branch from 6bf2b48 to d3517ce Compare October 26, 2026 10:59
@Mercurrial
Mercurrial marked this pull request as ready for review October 26, 2026 10:59
@Mercurrial
Mercurrial merged commit 191ff8f into main Oct 26, 2026
1 check passed
@Mercurrial
Mercurrial deleted the claude/determined-hypatia-tw8a26 branch October 26, 2026 13:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants