Skip to content

Monitor version number for release #400

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

blarghmatey
Copy link
Member

What are the relevant tickets?

N/A

Description (What does it do?)

Updates Doof to be able to check for version numbers when validating deployments. Also migrates to use UV for specifying the Python version and dependencies and upgrades the version of Python used.

How can this be tested?

Add a JSON file with a "version" key as the watched file in learn-ai and verify that the next production release gets detected properly

Additional Context

Doof checks the hash against the release-candidate and release branches respectively. The git hash for each branch is different. For applications deployed using Docker (e.g. learn-ai) we build the container once from the release-candidate branch and don't rebuild for production, which leads to Doof not seeing the hash that it is expecting. This updates the behavior to check against the version number that is being deployed to identify when the release is available.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Hello @blarghmatey, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

Summary of Changes

This pull request modifies Doof to validate deployments by checking version numbers instead of relying solely on git hashes. It also migrates the project to use UV for Python version and dependency management, and upgrades the Python version. The changes involve updating the _wait_for_deploy_with_alerts function to accept an expected_version parameter, modifying the _wait_for_deploy_rc and _wait_for_deploy_prod functions to use the release PR title's version, and updating tests to include the version check. Additionally, the pull request updates the build process to use uv and modernizes the publish.py script.

Highlights

  • Version-based Deployment Validation: Doof now validates deployments by checking the version number against the release PR title, addressing issues with Docker deployments where git hashes differ between release-candidate and release branches.
  • UV Migration: The project is migrated to use UV for Python version and dependency management, including an upgrade to a newer Python version (3.13) and updating the project structure to use pyproject.toml.
  • Build Process Modernization: The publish.py script is updated to use the build package instead of setup.py for creating source distributions and wheels, streamlining the PyPI publishing process.

Changelog

Click here to see the changelog
  • bot.py
    • Modified _wait_for_deploy_with_alerts to accept expected_version.
    • Modified _wait_for_deploy_rc to extract expected_version from the release PR.
    • Modified _wait_for_deploy_prod to extract expected_version from the release PR and remove get_version_tag call.
    • Updated the message sent to Slack to include the expected_version.
  • bot_test.py
    • Updated tests to pass expected_version to _wait_for_deploy_with_alerts.
    • Removed get_version_tag_mock from test_wait_for_deploy_prod and updated assertions to use release_pr.version.
  • publish.py
    • Removed direct pip install twine call.
    • Added pip install setuptools, pip install build, and pip install twine within the virtualenv context.
    • Replaced setup.py sdist and setup.py bdist_wheel calls with python -m build ..
    • Switched from call to check_call for build commands.
  • pyproject.toml
    • Added pyproject.toml to specify project metadata, dependencies, and build configuration using UV.
    • Specifies Python 3.13 as the required version.
    • Includes development dependencies such as black, codecov, pylint, and pytest.
  • requirements.txt
    • Removed, as dependencies are now managed by UV and specified in pyproject.toml.
  • test_requirements.txt
    • Removed, as test dependencies are now managed by UV and specified in pyproject.toml.
  • uv.lock
    • Added uv.lock to lock dependencies for reproducible builds.
  • wait_for_deploy.py
    • Modified fetch_release_hash to handle JSON responses with a 'version' key and validate the expected version.
    • Modified wait_for_deploy to accept expected_version and pass it to fetch_release_hash.
    • Added logging for version and hash checks, as well as error handling for deployment status checks.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.


A version to check,
A hash to inspect with care,
Doof watches, alerts.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@blarghmatey blarghmatey force-pushed the monitor_version_number_for_release branch from 4481264 to 210f137 Compare April 4, 2025 16:24
Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces version number monitoring for deployments, migrates to UV for Python dependencies, and upgrades the Python version. The changes look good overall, but there are a few areas that could be improved for clarity and robustness.

Summary of Findings

  • Error Handling in fetch_release_hash: The fetch_release_hash function catches json.JSONDecodeError but the exception message is not logged. Logging the exception message would help in debugging.
  • Clarity of Version Check Logic: The version check logic in fetch_release_hash could be made more explicit by combining the version and hash checks into a single conditional block.
  • Redundant Call Count Assertion: The test_upload_to_pypi test in publish_test.py has an incorrect call count assertion. It should be updated to reflect the actual number of calls.

Merge Readiness

The pull request is almost ready for merging. Addressing the error handling and version check logic in fetch_release_hash would improve the robustness of the code. Additionally, correcting the call count assertion in publish_test.py would ensure the test accurately reflects the code's behavior. I am unable to approve this pull request, and users should have others review and approve this code before merging. I recommend that the pull request not be merged until the above issues are addressed.

Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot reviewed 11 out of 12 changed files in this pull request and generated 1 comment.

Files not reviewed (1)
  • test_requirements.txt: Language not supported
Comments suppressed due to low confidence (1)

wait_for_deploy.py:33

  • Consider using a more specific exception type (e.g., ValueError) for handling version mismatches to improve error clarity.
raise Exception(

As we move to containerized deploys we don't want to have to build a new image to
incorporate he updated hash from the release branch. This adds the ability to expose a
JSON blog with a "version" key that Doof can monitor to determine if a release was deployed.
@blarghmatey blarghmatey force-pushed the monitor_version_number_for_release branch from 210f137 to 9ed482b Compare April 4, 2025 16:34
blarghmatey added a commit to mitodl/learn-ai that referenced this pull request Apr 4, 2025
In mitodl/release-script#400 Doof gains the ability to parse
versions. This adds the necessary information in the hash.txt to allow Doof to properly
detect production deployments of this app.
blarghmatey added a commit to mitodl/learn-ai that referenced this pull request Apr 4, 2025
In mitodl/release-script#400 Doof gains the ability to parse
versions. This adds the necessary information in the hash.txt to allow Doof to properly
detect production deployments of this app.
@blarghmatey blarghmatey force-pushed the monitor_version_number_for_release branch from 9ed482b to 6a90548 Compare April 4, 2025 17:16
Copy link
Contributor

@rhysyngsun rhysyngsun left a comment

Choose a reason for hiding this comment

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

One other thing that came to mind:

If we switch purely to version does that mean that when a version gets reused for RC (as they often do when we redo a release candidate), are we going to hit the same problem? This starts leaning towards some kind of data/incremented version instead.

@blarghmatey blarghmatey force-pushed the monitor_version_number_for_release branch 3 times, most recently from 95dd83a to d0e12d8 Compare April 8, 2025 17:32
@blarghmatey blarghmatey requested a review from rhysyngsun April 8, 2025 17:33
@blarghmatey blarghmatey force-pushed the monitor_version_number_for_release branch 3 times, most recently from 4f4420a to dcc88c9 Compare April 8, 2025 18:05
- Refactor `wait_for_deploy` to accept `expected_version` argument
- Update callers in `bot.py` to pass the version.
- Update tests in `wait_for_deploy_test.py` and `bot_test.py`.
- Replace deprecated `pkg_resources` with `packaging` for version parsing.
- Improve Python package publishing in `publish.py`:
  - Use `python -m build .` for building sdist and wheel.
  - Use `check_call` to ensure build errors are raised.
  - Fix virtual environment handling to ensure `build` module is found.
- Update GitHub Actions CI workflow to use `uv` instead of `pip`.
- Address various Pylint errors in `publish.py` and `wait_for_deploy.py`.
@blarghmatey blarghmatey force-pushed the monitor_version_number_for_release branch from dcc88c9 to f878d32 Compare April 8, 2025 18:07
@blarghmatey blarghmatey requested a review from Copilot April 8, 2025 18:27
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot reviewed 11 out of 13 changed files in this pull request and generated no comments.

Files not reviewed (2)
  • runtime.txt: Language not supported
  • test_requirements.txt: Language not supported
Comments suppressed due to low confidence (2)

publish_test.py:58

  • The expected call count increased from 1 to 5, reflecting changes in dependency installation. Please confirm that this new value correctly matches the updated behavior of the publish process.
assert call_mock.call_count == 5

.github/workflows/ci.yml:5

  • Switching from a specific Ubuntu version to 'ubuntu-latest' may impact consistency in the CI environment. Verify that this change is intentional and does not affect dependency behavior.
runs-on: ubuntu-latest

log = logging.getLogger(__name__)


async def fetch_release_hash(hash_url, *, expected_version=None):
Copy link
Contributor

Choose a reason for hiding this comment

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

This feels like this function is doing too much and it's becoming hard to follow/review - it's fetching and validating the version and/or hash.

Also it's raising exceptions but those don't appear to be caught anywhere so I think this would just crash wait_for_deploy on the first check and never resume.

I have a suggestion that involves a bit more changes but I think overall simplifies things quite a bit:

Define a new dataclass:

@dataclass
class HashAndVersion:
    hash: str
    version: str | None = None

    def __eq__(self, other):
        return (
            # always check for hash equality
            self.hash == other.hash and
            # only match on version if we got a version from expected and the JSON
            (self.version == other.version if all(self.version, other.version else True)
        )

Then add a field to RepoInfo for a watch_branch field (it can either be optional, defaulting to "release", or we can specify it for everything). This would be set to "release-candidate" for repos deployed in k8s. Add the data and parsing for this.

Then I think all you'd need to do would be to update the call to _wait_for_deploy_with_alerts in _wait_for_deploy_prod to pass watch_branch=repo_info.watch_branch and then in wait_for_deploy simply make this check:

        await fetch_release_hash(hash_url, expected_version=expected_version)
        != HashAndVersion(latest_hash, expected_version)

If I've pseudocoded this in my head right, that should make the following checks work:

  • For k8s:
    • If release-candidate, compare on hash from release-candidate and version from PR
    • If release, compare on hash from release-candidate and version from PR
  • Otherwise:
    • If release-candidate, compare on hash from release-candidate
    • If release, compare on hash from release

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