Skip to content

Add wait-for-builds polling for Launchpad build completion#111

Merged
rtibbles merged 2 commits intolearningequality:mainfrom
rtibblesbot:issue-107-0a1e6e
Feb 22, 2026
Merged

Add wait-for-builds polling for Launchpad build completion#111
rtibbles merged 2 commits intolearningequality:mainfrom
rtibblesbot:issue-107-0a1e6e

Conversation

@rtibblesbot
Copy link
Contributor

Summary

Adds a wait-for-builds subcommand to scripts/launchpad_copy.py that polls Launchpad until all builds for a source package reach a terminal state. This prevents the race condition where copy-to-series or promote operations proceed before Launchpad has finished building binaries.

The command operates in two phases:

  1. Source appearance: Polls getPublishedSources until the expected package+version appears in the PPA (filtering out Deleted/Superseded/Obsolete sources)
  2. Build completion: Polls getBuilds() on all matching sources until every build reaches a terminal state

CLI parameters: --package, --version, --ppa (default: kolibri-proposed), --timeout (default: 1800s), --interval (default: 60s). Exits 0 if all builds succeed, 1 on any failure or timeout.

Two new workflow jobs are inserted into the build_debian.yml release workflow:

  • wait_for_source_builds: after build_package, before copy_to_other_distributions
  • wait_for_copy_builds: after copy_to_other_distributions, before block_release_step/promote

References

Closes #107

Reviewer guidance

  • The core polling logic is in LaunchpadWrapper.wait_for_builds() and _poll_builds() — review these for correctness of the state machine (terminal states, failure detection, timeout handling)
  • The workflow changes add two new jobs with LP credentials handling — verify the needs dependency chain is correct
  • Tests mock time.time and time.sleep to avoid real delays; the side_effect sequences simulate time progression
  • The 4 skipped tests require ubuntu-distro-info which isn't available outside Ubuntu — this is expected
Test evidence

Test scenarios covered (48 passed, 4 skipped)

CLI argument parsing (13 tests):

  • wait-for-builds subcommand recognized with required --package and --version
  • Defaults: --ppa=kolibri-proposed, --timeout=1800, --interval=60
  • Custom values for all parameters accepted
  • Missing required args produce SystemExit

Build polling (14 tests):

  • Source appears immediately → builds checked → success
  • Source appears after retry (sleep called)
  • Timeout when source never appears → exit 1 with error message
  • Deleted/Superseded sources filtered out (treated as not-found)
  • All builds succeed across multiple architectures → exit 0
  • Checks ALL build records, not just first (amd64 ok + arm64 fail → exit 1)
  • Single build failure → exit 1 with arch, state, and web_link logged
  • Builds complete after retry (Currently building → Successfully built)
  • Build timeout (still building at deadline) → exit 1
  • Multiple sources all checked (cross-series after copy)
  • No builds yet → keeps waiting until they appear
  • Progress logging: "Waiting for builds: 2/3 complete, 1 building..."
  • Custom PPA name passed through to get_ppa()
  • Obsolete series handled gracefully during promote

Subcommand dispatch (3 tests):

  • main() dispatches wait-for-builds to cmd_wait_for_builds
  • Existing copy-to-series and promote dispatch unchanged
$ python3 -m pytest tests/ -v
48 passed, 4 skipped in 0.24s
$ ruff check scripts/ tests/
All checks passed!

$ ruff format --check scripts/ tests/
5 files already formatted

@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly

How was this generated?
  • Ran pre-flight CI checks (lint, format, tests) and verified all pass
  • Rebased onto the target branch and resolved any conflicts
  • Reorganized commit history into clean, logical commits
  • Audited the diff to ensure only issue-relevant files are changed
  • Built PR body from the repository's PR template with evidence blocks

Closes #107

Copy link
Member

@rtibbles rtibbles left a comment

Choose a reason for hiding this comment

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

Tested locally - seems to work, but I had some difficulties with dependencies.

The pyproject.toml doesn't contain any python dependencies for either test or regular operations.

I had to install:

  • launchpadlib
  • keyring
    To run the scripts

and pytest to run the tests.

rtibblesbot and others added 2 commits February 22, 2026 14:04
Add a `wait-for-builds` subcommand to launchpad_copy.py that polls
Launchpad until all builds for a source package reach a terminal state.

Phase 1 waits for the source package to appear in the PPA (handling the
delay between dput upload and Launchpad acceptance). Phase 2 polls
getBuilds() on all matching sources until every build succeeds, fails,
or times out.

CLI parameters: --package, --version, --ppa, --timeout (default 1800s),
--interval (default 60s). Returns exit code 0 on success, 1 on failure
or timeout, with clear error messages and progress logging.

Includes comprehensive tests covering: source appearance polling, build
completion polling, timeout handling, failure detection across all build
records, progress logging, and custom PPA support.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Insert two polling jobs into the release workflow:
- wait_for_source_builds: runs after build_package, before copy_to_series
- wait_for_copy_builds: runs after copy_to_series, before promote

This prevents the race condition where copy or promote operations proceed
before Launchpad has finished building binaries.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@rtibblesbot
Copy link
Contributor Author

Thanks for the review! Added Python dependencies to pyproject.tomllaunchpadlib and keyring as runtime dependencies, pytest and vcrpy as test dependencies.

Addressed 1/1 review items. 0 deferred.

@rtibbles rtibbles merged commit 4249221 into learningequality:main Feb 22, 2026
7 checks passed
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.

Add launchpad polling to determine when builds complete

2 participants