Skip to content

fix: include moder_update_updater.exe in GitHub Release and enable deterministic builds#325

Merged
ModerRAS merged 2 commits intomasterfrom
fix/update-package-include-updater-exe
Apr 26, 2026
Merged

fix: include moder_update_updater.exe in GitHub Release and enable deterministic builds#325
ModerRAS merged 2 commits intomasterfrom
fix/update-package-include-updater-exe

Conversation

@ModerRAS
Copy link
Copy Markdown
Owner

@ModerRAS ModerRAS commented Apr 26, 2026

Summary

  • Copy moder_update_updater.exe to the standalone publish directory before zipping for GitHub Release, so the full release package includes the updater (previously only present on B2)
  • Enable deterministic build flags (Deterministic, DeterministicSourcePaths, ContinuousIntegrationBuild) so unchanged assemblies produce identical SHA512 hashes across builds, making step/cumulative update packages on Backblaze B2 properly differential instead of containing every file

Details

Problem 1: Updater missing from GitHub Release

The build-standalone-assets job in push.yml copies moder_update_updater.exe to artifacts/update-feed/ (for B2 upload), but never to artifacts/standalone/ -- which is what gets zipped as TelegramSearchBot-win-x64-full-*.zip. Users downloading the full zip from GitHub Releases had no way to run the updater.

Problem 2: B2 differential packages contain all files

Without deterministic builds, .NET self-contained publish produces different binary hashes every build (even when source is identical), causing ComputeChangedFiles to detect every file as "changed". With Deterministic=true, the compiler produces reproducible output -- unchanged DLLs/exes will have identical hashes, and only truly changed files end up in step/cumulative packages.

Changes

  • .github/workflows/push.yml: Added Copy-Item to place moder_update_updater.exe in artifacts/standalone/ alongside the existing copy to artifacts/update-feed/
  • TelegramSearchBot/TelegramSearchBot.csproj: Added Deterministic, DeterministicSourcePaths, and ContinuousIntegrationBuild to the Release|AnyCPU property group

Summary by CodeRabbit

  • Chores
    • Enhanced build process and release packaging configuration for improved build reproducibility and artifact distribution.

…nable deterministic builds

- Copy moder_update_updater.exe to standalone dir so the full release zip includes the updater
- Enable deterministic builds (Deterministic, DeterministicSourcePaths, ContinuousIntegrationBuild)
  so unchanged assemblies produce identical hashes across builds, making differential update packages smaller
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 26, 2026

Warning

Rate limit exceeded

@ModerRAS has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 28 minutes and 32 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 28 minutes and 32 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 57b53097-15ad-4ff2-b154-40f7ec693123

📥 Commits

Reviewing files that changed from the base of the PR and between ffe89a9 and c8a99c1.

📒 Files selected for processing (1)
  • TelegramSearchBot.Test/Service/Todo/TodoServiceTests.cs
📝 Walkthrough

Walkthrough

The Release build configuration is updated to enforce deterministic compilation, and the CI workflow is modified to copy the built Moder.Update executable into both the update-feed and standalone artifact directories for inclusion in release packaging.

Changes

Cohort / File(s) Summary
CI/Build Workflow
.github/workflows/push.yml
Extended the "Build Moder.Update feed" step to copy moder_update_updater.exe into both .\\artifacts\\update-feed\\ and .\\artifacts\\standalone\\ directories for downstream packaging.
Build Configuration
TelegramSearchBot/TelegramSearchBot.csproj
Added Deterministic, DeterministicSourcePaths, and ContinuousIntegrationBuild properties set to true for the Release

Possibly related PRs

Poem

🐰 With deterministic builds so clean,
The updates now are split and seen—
In feed and standalone they dwell,
Reproducible—all working well! ✨

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and accurately summarizes both main changes: including moder_update_updater.exe in GitHub Release and enabling deterministic builds.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/update-package-include-updater-exe

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 26, 2026

🔍 PR检查报告

📋 检查概览

🧪 测试结果

平台 状态 详情
Ubuntu 🟢 成功 测试通过,产物已上传
Windows 🟢 成功 测试通过,产物已上传

📊 代码质量

  • ✅ 代码格式化检查
  • ✅ 安全漏洞扫描
  • ✅ 依赖包分析
  • ✅ 代码覆盖率收集

📁 测试产物

  • 测试结果 artifacts 数量: 2
  • 代码覆盖率已上传到Codecov

🔗 相关链接


此报告由GitHub Actions自动生成

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/push.yml (1)

298-303: ⚠️ Potential issue | 🟡 Minor

Reorder the updater copy to run before UpdateBuilder to maintain source-dir symmetry.

The current order runs UpdateBuilder (which reads from artifacts\standalone) before copying moder_update_updater.exe into artifacts\standalone. This creates a logical asymmetry: --prev-source-dir .\artifacts\prev-standalone will contain the updater (from the prior release), while --source-dir .\artifacts\standalone will not (it's only copied afterward on line 303).

UpdateBuilder's step package includes only files present in the current version—it doesn't track removals. However, the ordering is unclean and the updater will be redundantly included in the step package when it's already tracked separately via UpdaterChecksum in the catalog.

Suggest moving the copy of moder_update_updater.exe to artifacts\standalone to before invoking UpdateBuilder:

🔧 Proposed reordering
+        Copy-Item .\moder-update-bin\moder_update_updater.exe .\artifacts\standalone\moder_update_updater.exe -Force
         dotnet run --project .\TelegramSearchBot.UpdateBuilder\TelegramSearchBot.UpdateBuilder.csproj `
           -c Release `
           --no-build `
           -- `@builderArgs`
         Copy-Item .\moder-update-bin\moder_update_updater.exe .\artifacts\update-feed\moder_update_updater.exe -Force
-        Copy-Item .\moder-update-bin\moder_update_updater.exe .\artifacts\standalone\moder_update_updater.exe -Force

This ensures both source-dir and prev-source-dir include the updater, maintaining consistency.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/push.yml around lines 298 - 303, The job runs
TelegramSearchBot.UpdateBuilder (dotnet run --project ...
TelegramSearchBot.UpdateBuilder.csproj) before copying moder_update_updater.exe
into .\artifacts\standalone, causing .\artifacts\standalone to lack the updater
while .\artifacts\prev-standalone does include it; move the Copy-Item that
places moder_update_updater.exe into .\artifacts\standalone so it executes
before invoking UpdateBuilder (ensuring both --source-dir .\artifacts\standalone
and --prev-source-dir .\artifacts\prev-standalone contain the updater and avoid
redundant inclusion in the UpdateBuilder step).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@TelegramSearchBot/TelegramSearchBot.csproj`:
- Around line 22-24: Add repository-wide deterministic build properties so all
projects (including TelegramSearchBot.Common, TelegramSearchBot.Database,
TelegramSearchBot.LLM, TelegramSearchBot.Search, TelegramSearchBot.LLMAgent,
TelegramSearchBot.SubAgent and TelegramSearchBot) produce stable SHA512s: create
a Directory.Build.props at repo root with a Release-scoped PropertyGroup that
sets Deterministic, DeterministicSourcePaths, and ContinuousIntegrationBuild;
remove the redundant Release block from TelegramSearchBot.csproj afterward.
Because DeterministicSourcePaths=true requires SourceLink, either add a
SourceLink package (e.g., Microsoft.SourceLink.GitHub) to the projects that
produce PEs or set DeterministicSourcePaths=false in Directory.Build.props and
keep Deterministic=true to avoid build failures.

---

Outside diff comments:
In @.github/workflows/push.yml:
- Around line 298-303: The job runs TelegramSearchBot.UpdateBuilder (dotnet run
--project ... TelegramSearchBot.UpdateBuilder.csproj) before copying
moder_update_updater.exe into .\artifacts\standalone, causing
.\artifacts\standalone to lack the updater while .\artifacts\prev-standalone
does include it; move the Copy-Item that places moder_update_updater.exe into
.\artifacts\standalone so it executes before invoking UpdateBuilder (ensuring
both --source-dir .\artifacts\standalone and --prev-source-dir
.\artifacts\prev-standalone contain the updater and avoid redundant inclusion in
the UpdateBuilder step).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2904b9d1-d9b5-43ea-8f20-d9db2b601b15

📥 Commits

Reviewing files that changed from the base of the PR and between ee3d454 and ffe89a9.

📒 Files selected for processing (2)
  • .github/workflows/push.yml
  • TelegramSearchBot/TelegramSearchBot.csproj

Comment on lines +22 to +24
<Deterministic>true</Deterministic>
<DeterministicSourcePaths>true</DeterministicSourcePaths>
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify which projects in the solution carry deterministic flags and whether SourceLink is wired.
fd -e csproj | xargs -I{} sh -c 'echo "=== {} ==="; grep -nE "Deterministic|ContinuousIntegrationBuild|SourceLink" "{}" || echo "(none)"'

Repository: ModerRAS/TelegramSearchBot

Length of output: 1216


🏁 Script executed:

#!/bin/bash
# 1. Check lines 101-106 in TelegramSearchBot.csproj to verify the project references
echo "=== Project references in TelegramSearchBot.csproj (lines 101-106) ==="
sed -n '101,106p' TelegramSearchBot/TelegramSearchBot.csproj

echo ""
echo "=== Check if Directory.Build.props exists ==="
if [ -f Directory.Build.props ]; then
  echo "Directory.Build.props EXISTS"
  cat Directory.Build.props
else
  echo "Directory.Build.props DOES NOT EXIST"
fi

echo ""
echo "=== Check for SourceLink references in all .csproj files ==="
fd -e csproj | xargs grep -l "SourceLink\|sourcelink" || echo "No SourceLink found"

Repository: ModerRAS/TelegramSearchBot

Length of output: 883


🏁 Script executed:

#!/bin/bash
# Check the PropertyGroup context around the deterministic flags
echo "=== PropertyGroup context around lines 22-24 ==="
sed -n '16,30p' TelegramSearchBot/TelegramSearchBot.csproj

echo ""
echo "=== Check for publish profiles or artifact/standalone configuration ==="
find . -name "*publish*" -o -name "*.pubxml" | head -20

echo ""
echo "=== Check if artifacts/standalone is mentioned in build files ==="
grep -r "artifacts\|standalone" --include="*.csproj" --include="*.props" | head -10

Repository: ModerRAS/TelegramSearchBot

Length of output: 1061


Determinism flags missing from referenced projects — SHA512 comparison won't stabilize.

The PR objective is to make unchanged assemblies produce identical SHA512 hashes so ComputeChangedFiles only flags truly changed files. However, these flags are only added to TelegramSearchBot.csproj in a Release-specific PropertyGroup. The six referenced projects at lines 101–106 (TelegramSearchBot.Common, .Database, .LLM, .Search, .LLMAgent, .SubAgent) have no Deterministic, DeterministicSourcePaths, or ContinuousIntegrationBuild settings.

Each non-deterministic dependency will have a varying PE timestamp and MVID per build, so its file hash will change every run and the cumulative package logic will keep flagging them as changed even when nothing changed. The fix needs to be applied to every project whose output ends up in the build — preferably by centralizing it in a Directory.Build.props at the repo root so all projects pick it up uniformly.

Critical caveat: DeterministicSourcePaths=true requires SourceLink/source-control integration to avoid build failures. No SourceLink package is currently configured in any project. Either add Microsoft.SourceLink.GitHub (or equivalent) to the projects, or set DeterministicSourcePaths=false while keeping Deterministic=true.

♻️ Suggested approach: centralize via Directory.Build.props

Create Directory.Build.props next to the solution file:

<Project>
  <PropertyGroup Condition="'$(Configuration)'=='Release'">
    <Deterministic>true</Deterministic>
    <DeterministicSourcePaths>true</DeterministicSourcePaths>
    <ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
  </PropertyGroup>
</Project>

Then remove the duplicated block from TelegramSearchBot.csproj:

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-    <Deterministic>true</Deterministic>
-    <DeterministicSourcePaths>true</DeterministicSourcePaths>
-    <ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
   </PropertyGroup>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@TelegramSearchBot/TelegramSearchBot.csproj` around lines 22 - 24, Add
repository-wide deterministic build properties so all projects (including
TelegramSearchBot.Common, TelegramSearchBot.Database, TelegramSearchBot.LLM,
TelegramSearchBot.Search, TelegramSearchBot.LLMAgent, TelegramSearchBot.SubAgent
and TelegramSearchBot) produce stable SHA512s: create a Directory.Build.props at
repo root with a Release-scoped PropertyGroup that sets Deterministic,
DeterministicSourcePaths, and ContinuousIntegrationBuild; remove the redundant
Release block from TelegramSearchBot.csproj afterward. Because
DeterministicSourcePaths=true requires SourceLink, either add a SourceLink
package (e.g., Microsoft.SourceLink.GitHub) to the projects that produce PEs or
set DeterministicSourcePaths=false in Directory.Build.props and keep
Deterministic=true to avoid build failures.

…nt failure

The test hardcoded dueAt to 2026-04-25 which became a past date after April 26, causing remindAt (now-5min) > dueAt (yesterday) validation to reject the todo creation. Changed to relative dates (dueAt=tomorrow, remindAt=+1hour).
@ModerRAS ModerRAS merged commit 2c66d14 into master Apr 26, 2026
5 checks passed
@ModerRAS ModerRAS deleted the fix/update-package-include-updater-exe branch April 26, 2026 05:43
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.

1 participant