Skip to content

Migrate to copier-nuxt-python-intranet-app - #72

Draft
ejfine wants to merge 17 commits into
mainfrom
migrate-to-nuxt-template
Draft

ejfine wants to merge 17 commits into
mainfrom
migrate-to-nuxt-template

Conversation

@ejfine

@ejfine ejfine commented Sep 29, 2026

Copy link
Copy Markdown
Contributor

Link to Issue or Message thread

Why is this change necessary?

cloud-courier was instantiated from copier-python-package-template, which has no notion of installing the
agent as a Windows service. Nothing in the repo or the docs covered service installation at all —
docs/configure-lab-computers.rst only covered upload configuration.

copier-nuxt-python-intranet-app supplies a signed-capable MSI, service registration, an LSA rights grant,
crash dumps, and a Windows CI job that installs and exercises the service. It is also actively maintained
and sits on a much newer copier-base-template pin.

How does this change address the issue?

Switches _src_path to the nuxt template and reconciles the repo with the layout it expects.

  • src/cloud_courier/ → backend/src/backend_api/, tests alongside it, root pyproject.toml/uv.lock/
    pyinstaller.spec removed in favour of the backend/ ones. backend/pyproject.toml carries version
    0.0.5 to continue the existing version line, which is what release.yaml tags from.
  • The upload agent now runs from the FastAPI app's lifespan alongside uvicorn, sharing one stop event, so
    SCM stop drains the agent instead of killing it. This is the only non-mechanical change in the PR; the
    rest is relocation or restoration.
  • Sphinx docs and Codecov are restored as repo-local files, since the nuxt template ships neither.

Scope is deliberately minimal. The MSI and Windows service arrive with the template but are not wired up
for real use: nothing yet supplies the agent with --aws-region or --stop-flag-dir, so a real install
would register a service that fails on first start. That is fine for now because the repo shipped no
installer before this, so nothing regresses, and the manual deployment described in docs/installation.rst
is still accurate. The open questions are recorded as TODOs above _install_service in
backend/tests/windows_service/test_service_lifecycle.py.

What side effects does this change have?

Deliberate divergences from the upstream template, each commented in place so they are not mistakenly
backported:

  • Windows is removed from the unit-test-backend matrix. use_windows_in_ci has to be true to build the
    MSI, but nearly every backend unit test reaches AWS through a localstack service container, and GitHub
    only runs Linux service containers on Linux runners.
  • That localstack service container and the AWS profile step are restored to CI, and localstack is restored
    to the devcontainer compose file. A devcontainer rebuild is needed to pick that up, and also to move
    the python_venv volume to backend/.venv; until then the venv sits on the slow host mount.
  • build-docs and the Codecov upload are re-added to CI; the template has neither.
  • A new --skip-upload-agent flag lets the E2E and Windows service harnesses serve the API without the
    agent, since CI runners have no AWS to reach.

Behaviour changes worth knowing about:

  • Log files are now cloud-courier-backend.log rather than cloud-courier-courier.log, and the JSON
    subsystem field changes, because the template's logger_config.py replaced ours.
  • --aws-region and --stop-flag-dir are no longer required=True at the argparse layer. They are
    validated in start_courier, which raises naming the missing flag, so a misconfigured deployment still
    fails immediately and says why.
  • The installer's manufacturer name was corrected, which also moves the Program Files directory, the
    ProgramData log directory and an HKLM registry key. Nothing has been released from this branch, so no
    machine carries the old paths. installer_upgrade_code and WINDOWS_SERVICE_NAME are deliberately
    unchanged.

How is this change tested?

CI is green on every job: 120 backend unit tests at 100% coverage, frontend unit tests, both exe builds, the
MSI build, both E2E suites and the Windows service smoke tests.

Two things gained real coverage they did not have before:

  • The agent-and-server seam is covered by a new backend/tests/unit/test_courier_lifespan.py: the agent is
    skipped when unconfigured, started with the right arguments, the stop event propagates on shutdown, a
    crash is recorded and produces a non-zero exit, and a hung agent logs the join timeout.
  • The version the frozen executable reports is now asserted from the E2E suite against a running binary on
    both Linux and Windows. The test it replaces, tests/executable/test_intact.py, never ran anywhere: it
    was marked only_exe, and no job ever passed --only-exe.

Other

Three artifacts a fresh instantiation needs but does not produce had to be generated, each found by a
separate CI run: pnpm-lock.yaml, frontend/public/favicon.ico (the installer icon), and the frontend
Kiota client under frontend/app/generated/. The favicon one is a template bug, filed upstream as
copier-nuxt-python-intranet-app#235.

Follow-up work found along the way is recorded as TODOs in the code rather than in a tracker: the
/api/shutdown route calls os._exit and can orphan S3 multipart parts; the agent treats AWS being
unreachable at startup as fatal; the stop-flag-file mechanism is superseded by the service stop event but
cannot be removed until whatever writes those files is found; the unit tests only ever run on Linux for a
Windows-only product; and an upload-delay retry whose cadence is bound to network latency.

🤖 Generated with Claude Code

ejfine and others added 15 commits September 21, 2026 16:10
Switch _src_path from copier-python-package-template to
copier-nuxt-python-intranet-app (v0.0.188). Copier applied cleanly with
no .rej files.

This commit is the raw template output only. The existing src/, tests/,
pyproject.toml, pyinstaller.spec, docs/, .readthedocs.yaml and
.github/.codecov.yml are untouched at the repo root and are reconciled in
the commits that follow.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Relocate the package and tests into the layout the nuxt template expects,
renaming cloud_courier -> backend_api.

Collisions resolved:
- logger_config.py: dropped ours in favour of the template's (a strict
  superset). SUBSYSTEM_NAME goes "courier" -> "backend", so log files are
  now cloud-courier-backend.log and the JSON "subsystem" field changes.
- cli.py: its seven arguments folded into the template's
  entrypoint/parser.py; the file is deleted. get_version() has a different
  shape there (bare version, prepend_v flag), so main.py's instance-tag
  write uses get_version(prepend_v=True) to keep the tag value identical
  for the cloud-courier-infrastructure Pulumi code.
- conftest.py: localstack_profile, flag_file_dir, --only-exe and its
  collection hook merged into backend/tests/conftest.py; the only_exe
  marker is restored to pytest.ini.

Making --aws-region and --stop-flag-dir required broke five of the
template's own arg-parsing tests and its crash-dump resolution, which
silently falls back to the temp dir when the argv it is handed does not
parse. Both are fixed by filling in GENERIC_REQUIRED_CLI_ARGS, the seam
the template leaves for exactly this.

backend/pyproject.toml takes version 0.0.5, continuing the version line
from the deleted root pyproject.toml, since release.yaml now reads the
version from there. The OpenAPI snapshot is regenerated for that change.

Also restores the localstack service to .devcontainer/docker-compose.yml,
which the template dropped. This needs a devcontainer rebuild to take
effect -- and so does the python_venv volume, which the template moved to
backend/.venv. Until that rebuild, backend/.venv sits on the 9p Windows
mount, where botocore's per-client scan of its ~400 service data
directories is slow enough to blow past the thread timeouts in
test_main.py. The suite is green (113 passed, 1 skipped, 20s) against a
venv on a normal filesystem.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The exe runs backend_api.entrypoint.cli.entrypoint, which never reached
main.entrypoint, so the upload agent was dead code after the tree move.
Fold it into the server's lifecycle instead.

main.entrypoint becomes start_courier(cli_args, *, stop_event). start_app
stashes the CLI arguments and the stop event on app.state, and the app's
lifespan reads them to run the agent on its own thread, joining it on
teardown. This follows the app.state.port convention in the sibling
weight-sensor-driver repo, and ties the agent to uvicorn's lifecycle so
there is one shutdown chain rather than two:

    SvcStop -> stop_event -> server.should_exit -> uvicorn shutdown
            -> lifespan teardown -> agent stops, thread joins

MainLoop now takes that stop event and waits on it instead of sleeping
between iterations, so a shutdown is noticed immediately rather than
after the remainder of the idle interval. The join is bounded at 20s,
inside the 30s grace period SvcStop allows. Whatever stops the agent
stops the server with it, and a crashed agent exits non-zero so the
service control manager does not read it as a clean admin stop.

--aws-region and --stop-flag-dir are no longer required by argparse.
Requiring them would have forced every caller that only wants the server
to invent placeholder values, and it does not help the E2E runners, which
have no AWS account to reach. They are validated in start_courier
instead, where a misconfigured deployment still fails immediately and
says which argument is missing. The new --skip-upload-agent lets the E2E
and Windows service harnesses serve the API alone. This also restores
tests/unit/entrypoint/test_arg_parsing.py and test_crash_dump.py to their
template versions.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Two deliberate divergences from the upstream template, both in the
unit-test-backend job, both commented in place so a future copier update
does not quietly revert them and a reviewer does not try to backport them.

use_windows_in_ci has to be true for the MSI installer to be built, which
also puts a Windows runner on this matrix. Nearly every backend unit test
reaches AWS through a localstack service container, and GitHub runs Linux
service containers only on Linux runners, so the Windows entry is removed
here while build-backend and build-installer keep theirs.

The template ships no service containers at all, so localstack and the
AWS profile step are restored from the pre-migration workflow. The
profile script already resolves the endpoint to localhost under
GITHUB_ACTIONS, which is what the published port maps to.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copier left frontend/package.json and pnpm-workspace.yaml without a
pnpm-lock.yaml, so the Pre-commit job failed with ERR_PNPM_NO_LOCKFILE.
That job gates the whole workflow, so every other job was skipped and
nothing on this branch had been exercised by CI at all.

Generated from the repo root with pnpm 12.4.2, so the workspace overrides
and allowBuilds settings apply: 951 packages.

The devcontainer context hash is regenerated by its pre-commit hook,
which tracks lockfiles.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Two CI failures from the first run that got past the pre-commit gate.

build-installer died on WIX0103: Product.wxs requires
$(BrandingDir)\favicon.ico, and installer_branding_dir defaults to
frontend/public, which the template never creates. Add that favicon,
copied from the backend's static one. A Nuxt app wants a public favicon
regardless.

The Playwright suite launches the executable itself, in
frontend/tests/e2e/global-setup.ts, separately from the Python
app_bootup.start_exe helper. It was still starting the agent, which
cannot reach AWS from a CI runner, so the agent raised
MissingCourierArgumentError, set the shared stop event and took the
server down with it before it ever bound its port. Pass
--skip-upload-agent there too.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
frontend/tests/e2e/fixtures.ts imports the Kiota-generated backend client,
but instantiation never produced it, so Playwright could not resolve the
import and reported "Cannot find package '~'" followed by "No tests found".

Generated with `task gen-frontend-openapi-client`. The output lands under
frontend/app/generated/ rather than frontend/generated/, because Nuxt
aliases ~ to the app directory.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The nuxt template ships no docs scaffold, so ci.yaml lost the job that
built them, and .readthedocs.yaml still installed the project with
`path: .` even though the root pyproject.toml is gone, which would have
broken the ReadTheDocs build.

Nothing in the docs imports the package: every page is hand-written
reStructuredText with no autodoc directives, and conf.py loads
sphinx.ext.autodoc without any page using it. A -W build with only
docs/requirements.txt installed succeeds, so the install entry is dropped
rather than repointed at backend/.

The new build-docs job installs the same way, via
`uv run --no-project --with-requirements requirements.txt`, so CI and
ReadTheDocs cannot drift apart. Sphinx stays out of backend/pyproject.toml
since the backend does not need it.

Also drops the copier-python-package-template entry from
.config/.copier-managed-files.json. This repo no longer instantiates from
that template, and three of the files the entry listed are deleted. The
warning banners in the docs files said to backport changes there, so they
now say the files are maintained here instead.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The nuxt template does not use Codecov, so the upload step went with the
workflow it replaced, leaving .github/.codecov.yml orphaned and the badge
missing from the README.

Two differences from the step this replaces: the report is at
backend/coverage.xml, because uv --directory runs pytest with backend/ as
its working directory, and the matrix.JOB_MATCHING_DEV_ENV guard is gone
since that variable no longer exists now the matrix is a single Linux
entry. The dependabot guard stays.

Also restores the ReadTheDocs badge, dropped by the same template switch.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- initialize-command.sh writes .devcontainer/.env so the compose bind
  mount can be retargeted when VS Code clones into a container volume,
  and docker-compose.yml reads it via WORKSPACE_MOUNT_TARGET
- build-installer gains the Windows long-file-paths step
- the XML formatter no longer rewrites .wxs files, which it was making
  unreadable by sorting and joining attributes
- install-ci-tooling.py refactor and extension version bumps

One hunk was rejected, in the unit-test-backend job, because the template
inserted its long-file-paths step exactly where this repo removes the
Windows runner and adds the localstack service container. Re-applied by
hand. That step is dropped along with the Windows entry: it is a no-op on
Linux, and keeping it would imply the matrix still has a Windows runner.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
installer_manufacturer was answered "Lab Automation and SCreening" at
instantiation. Re-answered and regenerated.

Beyond the displayed name, this also corrects the install directory under
Program Files, the ProgramData log directory and the HKLM registry key,
all of which derive from that answer. Nothing has been released from this
branch, so no installed machine carries the misspelled paths.

installer_upgrade_code and WINDOWS_SERVICE_NAME are deliberately
unchanged: the upgrade code identifies MSI upgrades for the life of the
product, and the service name is the identity the service control manager
keys on. Only the display name moves.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A too-new file is re-queued rather than dropped, so nothing is lost, but
it is only reconsidered on the next loop iteration, and every iteration
makes an STS call. How long the file waits therefore tracks network
latency rather than delay_seconds_before_upload. Separately, _boot_up
stamps its events with the moment the file was discovered instead of the
file's mtime, so a long-settled file waits out the full delay again after
every restart.

Both surfaced as an intermittent failure in
TestInitialFolderSearch::test_Given_folder_config_includes_subfolders...,
which allows one second for the upload to land.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
tests/executable/test_intact.py ran the built executable with --version
and asserted the output started with "v". It never ran anywhere: it was
marked only_exe, the collection hook skipped that marker unless
--only-exe was passed, and no job ever passed it. The file still carried
a TODO to wire it into CI.

The template's E2E suite now launches the same executable for real and
drives it over HTTP, so the version assertion moves there, into a
repo-specific spec that runs on both Linux and Windows. It covers
slightly more than the old test did: the version is resolved at runtime
from installed package metadata, so this fails if a PyInstaller build
stops bundling that metadata, which is only observable once frozen.

With nothing left carrying the marker, the --only-exe option, the
collection hook and the only_exe marker registration all go too.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Every test in this file installs the service with --skip-upload-agent, so
it covers the service lifecycle rather than the agent running under it.
That gap is deliberate for now: the MSI arrives with the nuxt template,
the repo shipped no installer before it, and wiring it up for lab use is
out of scope for the migration.

The four open questions are recorded where that gap is masked. The first
two would each produce a service that fails on a real machine: nothing
supplies --aws-region or --stop-flag-dir, and the AWS credentials are
read from LocalSystem's profile, so the installer's custom-account option
cannot authenticate.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The migration surfaced several things worth fixing that are out of scope
for it. Each is recorded where someone would actually hit it rather than
in a tracker nobody reads:

- the /api/shutdown route calls os._exit, which skips the multipart abort
  handler and so can orphan parts in the bucket, and is unauthenticated
  on a service whose bind address is operator-selectable
- the upload agent treats AWS being unreachable at startup as fatal and
  takes the server down with it, which is also why the E2E and Windows
  service harnesses have to pass --skip-upload-agent
- the stop-flag-file mechanism is superseded by the service stop event,
  but cannot be removed until whatever writes those files is found
- the unit tests only ever run on Linux for a Windows-only product, which
  needs the AWS-touching tests moved off localstack first
- the MSI installer is not yet documented because it is not yet usable

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 166 files, which is 66 over the limit of 100.

To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch.

Upgrade to a paid plan to raise the limit.

This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry.

⚙️ Run configuration

Configuration used: Repository: LabAutomationAndScreening/cloud-courier/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 8a3300b9-b43e-4384-9af7-a0322d3704dd

📥 Commits

Reviewing files that changed from the base of the PR and between b1de349 and 1eea6d9.

⛔ Files ignored due to path filters (19)
  • backend/src/static/favicon.ico is excluded by !**/*.ico
  • backend/tests/e2e/generated/open_api/backend/api/api_request_builder.py is excluded by !**/generated/**
  • backend/tests/e2e/generated/open_api/backend/api/healthcheck/healthcheck_request_builder.py is excluded by !**/generated/**
  • backend/tests/e2e/generated/open_api/backend/api/shutdown/shutdown_request_builder.py is excluded by !**/generated/**
  • backend/tests/e2e/generated/open_api/backend/backend_client.py is excluded by !**/generated/**
  • backend/tests/e2e/generated/open_api/backend/models/h_t_t_p_validation_error.py is excluded by !**/generated/**
  • backend/tests/e2e/generated/open_api/backend/models/healthcheck_response.py is excluded by !**/generated/**
  • backend/tests/e2e/generated/open_api/backend/models/problem_details.py is excluded by !**/generated/**
  • backend/tests/e2e/generated/open_api/backend/models/shutdown_response.py is excluded by !**/generated/**
  • backend/tests/e2e/generated/open_api/backend/models/validation_error.py is excluded by !**/generated/**
  • backend/uv.lock is excluded by !**/*.lock
  • frontend/app/generated/open-api/backend/api/healthcheck/index.ts is excluded by !**/generated/**
  • frontend/app/generated/open-api/backend/api/index.ts is excluded by !**/generated/**
  • frontend/app/generated/open-api/backend/api/shutdown/index.ts is excluded by !**/generated/**
  • frontend/app/generated/open-api/backend/backendClient.ts is excluded by !**/generated/**
  • frontend/app/generated/open-api/backend/kiota-lock.json is excluded by !**/generated/**
  • frontend/app/generated/open-api/backend/models/index.ts is excluded by !**/generated/**
  • frontend/public/favicon.ico is excluded by !**/*.ico
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (166)
  • .coderabbit.yaml
  • .config/.copier-answers.yml
  • .config/.copier-managed-files.json
  • .config/eslint-rules/istanbul-ignore-if-must-throw.mjs
  • .config/pyrefly.mutmut.toml
  • .config/pyrefly.toml
  • .config/ruff.toml
  • .config/taskfiles/backend.yaml
  • .config/taskfiles/codegen.yaml
  • .config/taskfiles/executable-stack.yaml
  • .config/taskfiles/frontend.yaml
  • .config/vacuum-functions/bodyDescription.js
  • .config/vacuum-functions/bodyExample.js
  • .config/vacuum-functions/resourcesPlural.js
  • .config/vacuum-ignore.yaml
  • .config/vacuum-ruleset.yaml
  • .devcontainer/Dockerfile
  • .devcontainer/code-artifact-auth.sh
  • .devcontainer/devcontainer.json
  • .devcontainer/docker-compose.yml
  • .devcontainer/envs.json
  • .devcontainer/initialize-command.sh
  • .devcontainer/install-ci-tooling.py
  • .github/.codecov.yml
  • .github/actions/ecr-auth/action.yml
  • .github/dependabot.yml
  • .github/workflows/build-docker-image.yaml
  • .github/workflows/build-installer.yaml
  • .github/workflows/ci.yaml
  • .github/workflows/git_tag.py
  • .github/workflows/release.yaml
  • .gitignore
  • .pre-commit-config.yaml
  • .readthedocs.yaml
  • AGENTS.md
  • README.md
  • Taskfile.yaml
  • backend/.coveragerc
  • backend/.python-version
  • backend/kiota_nullable_fixer.py
  • backend/pyinstaller.spec
  • backend/pyproject.toml
  • backend/src/__init__.py
  • backend/src/backend_api/__init__.py
  • backend/src/backend_api/app_def.py
  • backend/src/backend_api/app_runner.py
  • backend/src/backend_api/aws_credentials.py
  • backend/src/backend_api/camel_case_model.py
  • backend/src/backend_api/constants.py
  • backend/src/backend_api/courier_config_models.py
  • backend/src/backend_api/entrypoint/__init__.py
  • backend/src/backend_api/entrypoint/cli.py
  • backend/src/backend_api/entrypoint/crash_dump.py
  • backend/src/backend_api/entrypoint/grant_rights.py
  • backend/src/backend_api/entrypoint/parser.py
  • backend/src/backend_api/entrypoint/service_install_password.py
  • backend/src/backend_api/entrypoint/win_service.py
  • backend/src/backend_api/fast_api_exception_handlers.py
  • backend/src/backend_api/jinja_constants.py
  • backend/src/backend_api/load_config.py
  • backend/src/backend_api/logger_config.py
  • backend/src/backend_api/main.py
  • backend/src/backend_api/openapi_problem_responses.py
  • backend/src/backend_api/openapi_schema_simplifier.py
  • backend/src/backend_api/py.typed
  • backend/src/backend_api/upload.py
  • backend/src/entrypoint.py
  • backend/src/static/.gitignore
  • backend/tests/__init__.py
  • backend/tests/conftest.py
  • backend/tests/e2e/__init__.py
  • backend/tests/e2e/app_bootup.py
  • backend/tests/e2e/conftest.py
  • backend/tests/e2e/jinja_constants.py
  • backend/tests/unit/__init__.py
  • backend/tests/unit/__snapshots__/test_basic_server_functionality/test_openapi_schema.json
  • backend/tests/unit/conftest.py
  • backend/tests/unit/constants.py
  • backend/tests/unit/entrypoint/__init__.py
  • backend/tests/unit/entrypoint/fixtures.py
  • backend/tests/unit/entrypoint/test_arg_parsing.py
  • backend/tests/unit/entrypoint/test_crash_dump.py
  • backend/tests/unit/entrypoint/test_entrypoint.py
  • backend/tests/unit/entrypoint/test_grant_rights.py
  • backend/tests/unit/entrypoint/test_service_install_password.py
  • backend/tests/unit/entrypoint/test_service_subcommand.py
  • backend/tests/unit/entrypoint/test_stopping_behavior.py
  • backend/tests/unit/example_data_files/3_bytes.txt
  • backend/tests/unit/example_data_files/50_bytes.txt
  • backend/tests/unit/example_windows_aws_creds.ini
  • backend/tests/unit/fixtures.py
  • backend/tests/unit/snapshot.py
  • backend/tests/unit/spy_helpers.py
  • backend/tests/unit/test_aws_creds.py
  • backend/tests/unit/test_basic_server_functionality.py
  • backend/tests/unit/test_camel_case_model.py
  • backend/tests/unit/test_checksums.py
  • backend/tests/unit/test_courier_lifespan.py
  • backend/tests/unit/test_fast_api_exception_handlers.py
  • backend/tests/unit/test_folder_monitoring.py
  • backend/tests/unit/test_load_config.py
  • backend/tests/unit/test_main.py
  • backend/tests/unit/test_metrics.py
  • backend/tests/unit/test_openapi_problem_responses.py
  • backend/tests/unit/test_upload.py
  • backend/tests/windows_service/__init__.py
  • backend/tests/windows_service/conftest.py
  • backend/tests/windows_service/test_service_lifecycle.py
  • cloud-courier.code-workspace
  • deployment/deploy.bat
  • deployment/docker-compose.yaml
  • docs/Makefile
  • docs/conf.py
  • docs/index.rst
  • docs/installation.rst
  • docs/requirements.txt
  • frontend/app/app.config.ts
  • frontend/app/assets/css/main.css
  • frontend/app/layouts/default.vue
  • frontend/app/pages/index.vue
  • frontend/eslint.config.mjs
  • frontend/eslint.shared.mjs
  • frontend/kiota_nullable_fixer.py
  • frontend/nuxt.config.ts
  • frontend/package.json
  • frontend/playwright.config.ts
  • frontend/scripts/postinstall.mjs
  • frontend/tests/compiled/index.spec.ts
  • frontend/tests/e2e/application-behavior/backend-behavior.spec.ts
  • frontend/tests/e2e/application-behavior/version.spec.ts
  • frontend/tests/e2e/compose.ts
  • frontend/tests/e2e/fixtures.ts
  • frontend/tests/e2e/global-setup.ts
  • frontend/tests/e2e/global-teardown.ts
  • frontend/tests/e2e/helpers/vrt-masks.ts
  • frontend/tests/e2e/helpers/vrt.ts
  • frontend/tests/e2e/index.spec.ts
  • frontend/tests/e2e/ports.ts
  • frontend/tests/setup/auto-unmount.ts
  • frontend/tests/setup/bun-test-stub.ts
  • frontend/tests/setup/constants.ts
  • frontend/tests/setup/faker.ts
  • frontend/tests/unit/eslint-rules/istanbul-ignore-if-must-throw.spec.ts
  • frontend/tests/unit/pages/default-layout.nuxt.spec.ts
  • frontend/tests/unit/pages/index.nuxt.spec.ts
  • frontend/tsconfig.json
  • frontend/types/nuxt.config.d.ts
  • frontend/vitest.config.ts
  • installer/.gitignore
  • installer/ARCHITECTURE.md
  • installer/INSTALL.txt
  • installer/README.md
  • installer/license.rtf
  • installer/package.ps1
  • installer/scripts/install-service.ps1
  • installer/scripts/remove-service.ps1
  • installer/stage.ps1
  • installer/wix/Product.wxs
  • pnpm-workspace.yaml
  • pyinstaller.spec
  • pyproject.toml
  • pyrightconfig.json
  • pytest.ini
  • src/cloud_courier/cli.py
  • tests/executable/__init__.py
  • tests/executable/test_intact.py

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


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.

@codecov

codecov Bot commented Sep 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

Flag Coverage Δ
unittests 100.00% <100.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
backend/src/backend_api/__init__.py 100.00% <100.00%> (ø)
backend/src/backend_api/app_def.py 100.00% <100.00%> (ø)
backend/src/backend_api/app_runner.py 100.00% <100.00%> (ø)
backend/src/backend_api/aws_credentials.py 100.00% <ø> (ø)
backend/src/backend_api/camel_case_model.py 100.00% <100.00%> (ø)
backend/src/backend_api/constants.py 100.00% <ø> (ø)
backend/src/backend_api/courier_config_models.py 100.00% <ø> (ø)
backend/src/backend_api/entrypoint/cli.py 100.00% <100.00%> (ø)
backend/src/backend_api/entrypoint/crash_dump.py 100.00% <100.00%> (ø)
backend/src/backend_api/entrypoint/grant_rights.py 100.00% <100.00%> (ø)
... and 9 more
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

ejfine and others added 2 commits September 29, 2026 18:43
get_version returns a bare version by default, so dropping prepend_v
would silently change what cloud-courier-infrastructure reads off the
instance tag. The stubber compares against the mocked return value and
cannot tell whether prepend_v was passed, so assert the call itself.

Verified by dropping prepend_v and confirming the test fails.

The comment that used to sit on that line is removed rather than
reworded: the tag key already carries a warning about the Pulumi code
that reads it, and the behaviour is now enforced instead of described.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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