diff --git a/docs/design/off-queue/skip-stale-build.md b/docs/design/off-queue/skip-stale-build.md index 4c84bad..003ce45 100644 --- a/docs/design/off-queue/skip-stale-build.md +++ b/docs/design/off-queue/skip-stale-build.md @@ -14,18 +14,18 @@ **Стало.** Если `HSchool.AppHost.dll` и `HSchool.Server.dll` новее входов (C#, csproj, props, `global.json`), скрипт делает `dotnet run --no-build`. Иначе — `dotnet build`, потом `--no-build`. -`--rebuild` собирает всегда. Конфигурация (`-c` / `--configuration`) выбирает, какие dll сравнивать; -по умолчанию Debug, как у `dotnet run`. +`--rebuild` собирает всегда. Конфигурация (`-c` / `--configuration`) выбирает, какие dll сравнивать +и с какой конфигурацией звать `dotnet run`; по умолчанию Debug. **Почему.** Инкрементальный MSBuild всё равно оценивает Aspire SDK. `--no-build` это пропускает. Клиентский TypeScript и JSONC модов не входы: Vite и каталог читают диск (`ContentRoot`), а не `bin`. Тестовые проекты AppHost не ссылается — их правки запуск не пересобирают. -Правила «устарел ли билд» живут в `tools/apphost-uptodate.ps1` (то, что вызывает `run-aspire.ps1`) и в -`LaunchBuildStamp` (то, что проверяют тесты). Менять надо оба. +Правила «устарел ли билд» живут в трёх местах: `tools/apphost-uptodate.ps1` (Windows), +`needs_build` в `run-aspire.sh` (Ubuntu) и `LaunchBuildStamp` (то, что проверяют тесты). +Менять надо все три. ### Что не входит Голый `dotnet run --project src/HSchool.AppHost` по-прежнему собирает — так удобнее агентам с -грязным деревом. Linux-обёртки нет: точка входа Windows — `.cmd`. Протокол, HTTP и сейв не -трогаем. +грязным деревом. Протокол, HTTP и сейв не трогаем. diff --git a/run-aspire.ps1 b/run-aspire.ps1 index f12dc4b..00ceaf8 100644 --- a/run-aspire.ps1 +++ b/run-aspire.ps1 @@ -121,6 +121,7 @@ $run = @( '--project', (Join-Path $PSScriptRoot 'src\HSchool.AppHost\HSchool.AppHost.csproj') '--no-build' '--no-restore' + '-c', $configuration ) + $dotnetArgs & dotnet run @run $exitCode = $LASTEXITCODE diff --git a/run-aspire.sh b/run-aspire.sh index b79fc01..8da89c1 100644 --- a/run-aspire.sh +++ b/run-aspire.sh @@ -131,7 +131,7 @@ fi echo set +e -dotnet run --project src/HSchool.AppHost/HSchool.AppHost.csproj --no-build --no-restore "${dotnet_args[@]}" +dotnet run --project src/HSchool.AppHost/HSchool.AppHost.csproj --no-build --no-restore -c "$configuration" "${dotnet_args[@]}" exit_code=$? set -e diff --git a/src/HSchool.Client/src/ui/gameScreen.test.ts b/src/HSchool.Client/src/ui/gameScreen.test.ts index 66f2a7a..7e8161c 100644 --- a/src/HSchool.Client/src/ui/gameScreen.test.ts +++ b/src/HSchool.Client/src/ui/gameScreen.test.ts @@ -7,6 +7,7 @@ import { getLocale, setLocale } from '../i18n/locale.ts'; import { t } from '../i18n/strings.ts'; import { GameScreen } from './gameScreen.ts'; import type { School } from '../net/api.ts'; +import { patchChrome } from './viewState.ts'; vi.mock('../net/api.ts', async (importOriginal) => { const actual = await importOriginal(); @@ -272,6 +273,25 @@ describe('GameScreen view restore', () => { expect(screen.element.querySelector('.panel__body--fill')?.hasAttribute('hidden')).toBe(false); }); + it('reopens the last tab from sessionStorage when opening from the menu', () => { + history.replaceState(null, '', '/'); + patchChrome(1, { route: { tab: 'people' } }); + const screen = new GameScreen({ + onLeave: () => {}, + onSetRunning: () => {}, + onSetSpeed: () => {}, + onSkip: () => {}, + }); + document.body.append(screen.element); + screen.show(school()); + + const peopleTab = [...screen.element.querySelectorAll('.panel__tab')].find( + (button) => button.textContent === t('peopleTitle'), + ); + expect(peopleTab?.classList.contains('panel__tab--active')).toBe(true); + expect(location.search).toContain('tab=people'); + }); + it('keeps a guest on overview even when the URL asks for manage', () => { history.replaceState(null, '', '/?school=3&mode=manage'); const screen = new GameScreen({ diff --git a/tests/HSchool.Server.Tests/BuildChangelogTests.cs b/tests/HSchool.Server.Tests/BuildChangelogTests.cs index 6732403..ee83658 100644 --- a/tests/HSchool.Server.Tests/BuildChangelogTests.cs +++ b/tests/HSchool.Server.Tests/BuildChangelogTests.cs @@ -5,13 +5,15 @@ namespace HSchool.Server.Tests; public class BuildChangelogTests { private const string Head = "cccccccccccccccccccccccccccccccccccccccc"; + private const string Mid = "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"; private const string Mark = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; private const string Merge = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; private const string Unknown = "dddddddddddddddddddddddddddddddddddddddd"; private static readonly string Sample = string.Join('\n', Head, - $"{Head}\u001f2026-01-03T12:00:00Z\u001fAdd changelog window", + $"{Head}\u001f2026-01-04T12:00:00Z\u001fAdd changelog window", + $"{Mid}\u001f2026-01-03T12:00:00Z\u001fSkip stale AppHost build", $"{Mark}\u001f2026-01-02T12:00:00Z\u001fMark phase 54 in progress.", $"{Merge}\u001f2026-01-01T12:00:00Z\u001fMerge branch 'phase/53-weather-commute'"); @@ -22,9 +24,11 @@ public class BuildChangelogTests var visible = changelog.VisibleSince(Merge); - var commit = Assert.Single(visible); - Assert.Equal(Head, commit.Sha); - Assert.Equal("Add changelog window", commit.Subject); + Assert.Equal(2, visible.Count); + Assert.Equal(Mid, visible[0].Sha); + Assert.Equal("Skip stale AppHost build", visible[0].Subject); + Assert.Equal(Head, visible[1].Sha); + Assert.Equal("Add changelog window", visible[1].Subject); } [Fact] @@ -34,8 +38,9 @@ public class BuildChangelogTests var visible = changelog.VisibleSince(Mark); - var commit = Assert.Single(visible); - Assert.Equal("Add changelog window", commit.Subject); + Assert.Equal(2, visible.Count); + Assert.Equal("Skip stale AppHost build", visible[0].Subject); + Assert.Equal("Add changelog window", visible[1].Subject); } [Fact]