Merge stable into release-1.10#9529
Draft
infrahub-github-bot-app[bot] wants to merge 11 commits into
Draft
Conversation
…9506) * test: reusable lock recording adapter (#9439) * adding new lock test adapter * make the lock installation a fixture * use constants * typing issues * docs(test): trim LockTimeline docstring to one line Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(test): give RecordingLock an explicit typed constructor ty (the CI type checker) does not honor the mypy-style `# type: ignore[arg-type]`, so forwarding `*args: object` into InfrahubLock.__init__ failed ty check. Mirror the base constructor signature and forward named arguments instead, dropping the ignore. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test: accept a collection of lock names in assert_never_overlap Generalize assert_never_overlap to take a Collection[str] and verify that no two of the given locks are ever held simultaneously, instead of being limited to exactly two lock names. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test: split checkpoint assertion and require injected timeline - Replace the confusing `expected` flag on assert_held_at_checkpoint with two intent-revealing methods (assert_held_at_checkpoint / assert_not_held_at_checkpoint) delegating to a shared private helper. - Make `timeline` a required argument of RecordingLockRegistry instead of constructing one internally; install_recording_lock_registry now owns the default construction and injects it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(git): run object import outside the repository lock during sync (#9440) * create a seam to inject the new test adapter * refactor(git): split repo sync into git-state collection and import Extract collect_pending_imports() which performs the on-disk git mutations (fetch, branch creation, pull, commit-worktree pinning) and returns one entry per branch to import, instead of importing inline. sync() now runs the returned imports. Behavior is preserved; this is the seam that lets the import run outside the repository lock. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(git): run object import outside the repository lock during sync The repository lock is held to serialize git working-copy mutations, but it was also kept reserved during the object import, which is the slow phase when a branch carries conflicting data. Narrow the lock so it covers only the git-state work: - sync_repository now locks collect_pending_imports() and runs the imports after releasing the lock; the import target is injectable for testing. - sync_remote_repositories no longer wraps the origin sync and the reinit-fallback import in its outer repository lock; only the local init/reinit stays locked. Imports read from immutable per-commit worktrees pinned during the locked phase, so they no longer need the lock. Resolves the long lock reservation reported in IFC-1566. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(git): assert object import runs outside the repository lock Drives sync_repository with a recording lock registry and an injected recording importer, asserting the repository lock is not held when the import runs. Replaces the earlier pydantic-recast/flow-override scaffold with the injected-importer seam. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(git): create RepositorySyncer and RepositoryImporter components Replace the injected callable with a RepositoryImporter implementation that checkpoints into the lock timeline, asserting the repository lock is not held when the import runs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(git): drop redundant lock-scope comment in sync flow The narrow async-with scope is self-evident from the structure, and the intent is pinned by test_repository_lock_released_before_import. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(git): rename BranchImport to PendingObjectImport The dataclass models a pending import of repository objects (the target Infrahub branch and the source commit), not a branch. Rename it and the corresponding parameter so they read as queued import work, matching collect_pending_imports / pending_imports. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(git): call assert_not_held_at_checkpoint for the released-lock check The test invoked assert_held_at_checkpoint with an unsupported expected= kwarg. Use the adapter's dedicated assert_not_held_at_checkpoint, which expresses the intent that the repository lock is released before import. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(git): run object import outside the repository lock when adding a repository (#9441) * create a seam to inject the new test adapter * fix(git): run object import outside the repository lock during sync The repository lock is held to serialize git working-copy mutations, but it was also kept reserved during the object import, which is the slow phase when a branch carries conflicting data. Narrow the lock so it covers only the git-state work: - sync_repository now locks collect_pending_imports() and runs the imports after releasing the lock; the import target is injectable for testing. - sync_remote_repositories no longer wraps the origin sync and the reinit-fallback import in its outer repository lock; only the local init/reinit stays locked. Imports read from immutable per-commit worktrees pinned during the locked phase, so they no longer need the lock. Resolves the long lock reservation reported in IFC-1566. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(git): create RepositorySyncer and RepositoryImporter components Replace the injected callable with a RepositoryImporter implementation that checkpoints into the lock timeline, asserting the repository lock is not held when the import runs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(git): run object import outside the repository lock when adding a repository add_git_repository held the repository lock for the whole flow (local clone, default-branch object import, and origin sync). Narrow it to cover only the local clone and pinning its commit worktree; the import (via the injected RepositoryImporter) and the origin sync (via RepositorySyncer) now run after the lock is released. Imports read from the immutable per-commit worktree, so they no longer need the lock. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(git): assert add_git_repository imports outside the repository lock Add a no-mock test driving add_git_repository with a recording lock registry and a recording RepositoryImporter, asserting the repository lock is not held when the import runs. Update the existing mock-based create test for the new structure (import via the importer, sync via RepositorySyncer). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(git): drop redundant add_git_repository lock comment The narrow async-with scope is self-evident, and the import-outside-lock invariant is pinned by test_add_git_repository_releases_lock_before_import. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(git): restore create_commit_worktree as a local-only primitive Revert the on-demand remote fetch that was placed inside the worktree primitive. The fetch mutates the shared clone and belongs at the orchestration layer under the repository lock, not in a synchronous local working-copy primitive. The primitive again raises CommitNotFoundError when the commit is absent from the local clone. The fetch-on-miss safety net is re-homed under the repository lock in a follow-up commit. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(git): fetch a missing commit under the repository lock during init When a task references a commit that this worker's clone has not fetched yet, init() now fetches once under the repository lock and retries the worktree creation before surfacing CommitNotFoundError. The lock serializes the shared-clone fetch against concurrent resets and merges. This re-homes, at the orchestration layer, the recovery that previously lived inside the create_commit_worktree primitive, and keeps the safety net for the window the eventually-consistent sync fan-out leaves open: a dispatched task can outrun the fetch broadcast, or run on a restarted or newly added worker. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor: recording adapter test package + common class RecordingImporter * refactor: renamed locally overridden object * test(git): assert CommitNotFoundError message in worktree and init tests Add match= to the CommitNotFoundError assertions so they verify the commit SHA and repository identifier carried in the message, not just the exception type. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(git): tighten init fetch-retry comment Keep only the non-obvious rationale (the commit may be remote-only; the lock serializes shared-clone mutations); drop the unknowable database provenance and the enumerated operation list. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(git): use the recording lock adapter in the add-repo create test Replace the patched lock mock and the weak assert_any_call with install_recording_lock_registry and a timeline assertion that the repository lock was acquired, removing unittest.mock from the lock check in this test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * tests: use proper fixtures * refactor(git): extract RepositoryAdder and drop the add_git_repository importer param Move the locked clone/worktree and the outside-lock default-branch import into a RepositoryAdder component (sibling to RepositorySyncer). The task no longer needs an injectable importer parameter and always uses RepositoryFileImporter; the lock-release test injects the recording importer through the component instead. Invert the active-status check to return early. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(git): pin the sync import commit while the repository lock is held sync_remote_repositories resolved the import commit from the live branch head after releasing the lock, so a concurrent operation could advance the branch between lock release and import. Capture the commit while the lock is held and pass it to import_objects_from_files, matching the add and sync-via-syncer flows. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(git): isolate per-branch failures while collecting pending imports collect_pending_imports performed the git working-copy side of a sync for every branch and only then returned the imports for the caller to apply. A failure on a later branch aborted the whole collection, dropping the imports for branches already processed in the same run. Wrap each branch in its own error boundary so a single failing branch is logged and skipped while the rest are still imported. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(git): mark git_repos_dir as a usefixtures dependency git_repos_dir is needed only for its side effect (pointing the repositories directory at a temp path); it was declared as an unused parameter. Request it via usefixtures so the dependency is explicit and not mistaken for dead code. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor: split the method, too many statements * fix docstring collect_pending_imports * docs: clarify locked-phase scope in import docstring Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(git): log traceback when skipping a branch during import collection The per-branch error boundaries swallow the exception, so without exc_info the traceback was lost. Pass exc_info=exc to capture the skipped branch's call stack; the exception message is already part of the rendered traceback, so no separate error field is added. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(git): catch CommitNotFoundError in repository failure handlers create_commit_worktree now raises CommitNotFoundError, a sibling of RepositoryError rather than a subclass, so the existing per-branch isolation and failure-tagging handlers no longer caught a missing-commit failure they previously did. Add CommitNotFoundError explicitly to the relevant except clauses so a missing commit skips the branch / tags and skips the repo instead of aborting the whole sync. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore: add changelog fragment for repository lock narrowing [#6639] Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: update testing documentation for lock test adapter --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The artifact detail page offered no way to reload the artifact view after regenerating it, so the only way to see updated content was a full browser refresh. This adds the shared refresh button to the artifact header, next to the regenerate action. Clicking it refetches the artifact object and its rendered content in place, matching the refresh behavior already used on object detail pages. Closes #9335
… updates (#9298) Bumps the npm_and_yarn group with 5 updates in the /docs directory: | Package | From | To | | --- | --- | --- | | [@babel/plugin-transform-modules-systemjs](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-transform-modules-systemjs) | `7.29.0` | `7.29.4` | | [dompurify](https://github.com/cure53/DOMPurify) | `3.3.3` | `3.4.5` | | [fast-uri](https://github.com/fastify/fast-uri) | `3.1.0` | `3.1.2` | | [follow-redirects](https://github.com/follow-redirects/follow-redirects) | `1.15.11` | `1.16.0` | | [lodash](https://github.com/lodash/lodash) | `4.17.23` | `4.18.1` | Bumps the npm_and_yarn group with 1 update in the /frontend/app directory: [ws](https://github.com/websockets/ws). Bumps the npm_and_yarn group with 2 updates in the /frontend/packages/plugins/template directory: [postcss](https://github.com/postcss/postcss) and [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite). Updates `@babel/plugin-transform-modules-systemjs` from 7.29.0 to 7.29.4 - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.29.4/packages/babel-plugin-transform-modules-systemjs) Updates `dompurify` from 3.3.3 to 3.4.5 - [Release notes](https://github.com/cure53/DOMPurify/releases) - [Commits](cure53/DOMPurify@3.3.3...3.4.5) Updates `fast-uri` from 3.1.0 to 3.1.2 - [Release notes](https://github.com/fastify/fast-uri/releases) - [Commits](fastify/fast-uri@v3.1.0...v3.1.2) Updates `follow-redirects` from 1.15.11 to 1.16.0 - [Release notes](https://github.com/follow-redirects/follow-redirects/releases) - [Commits](follow-redirects/follow-redirects@v1.15.11...v1.16.0) Updates `lodash` from 4.17.23 to 4.18.1 - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](lodash/lodash@4.17.23...4.18.1) Updates `mermaid` from 11.12.3 to 11.15.0 - [Release notes](https://github.com/mermaid-js/mermaid/releases) - [Commits](https://github.com/mermaid-js/mermaid/compare/mermaid@11.12.3...mermaid@11.15.0) Updates `postcss` from 8.5.9 to 8.5.15 - [Release notes](https://github.com/postcss/postcss/releases) - [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md) - [Commits](postcss/postcss@8.5.3...8.5.15) Updates `webpack-dev-server` from 5.2.2 to 5.2.4 - [Release notes](https://github.com/webpack/webpack-dev-server/releases) - [Changelog](https://github.com/webpack/webpack-dev-server/blob/main/CHANGELOG.md) - [Commits](webpack/webpack-dev-server@v5.2.2...v5.2.4) Updates `ws` from 8.20.0 to 8.20.1 - [Release notes](https://github.com/websockets/ws/releases) - [Commits](websockets/ws@8.20.0...8.20.1) Updates `postcss` from 8.5.3 to 8.5.15 - [Release notes](https://github.com/postcss/postcss/releases) - [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md) - [Commits](postcss/postcss@8.5.3...8.5.15) Updates `vite` from 6.4.1 to 6.4.2 - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/v6.4.2/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v6.4.2/packages/vite) --- updated-dependencies: - dependency-name: "@babel/plugin-transform-modules-systemjs" dependency-version: 7.29.4 dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: dompurify dependency-version: 3.4.5 dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: fast-uri dependency-version: 3.1.2 dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: follow-redirects dependency-version: 1.16.0 dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: lodash dependency-version: 4.18.1 dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: mermaid dependency-version: 11.15.0 dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: postcss dependency-version: 8.5.15 dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: webpack-dev-server dependency-version: 5.2.4 dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: ws dependency-version: 8.20.1 dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: postcss dependency-version: 8.5.15 dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: vite dependency-version: 6.4.2 dependency-type: direct:development dependency-group: npm_and_yarn ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
When PREFECT_SERVER_EVENTS_MAXIMUM_RELATED_RESOURCES is 1, the chunk size derived from integer-dividing it by 2 became 0, raising ValueError from range() during batch submission. Floor the chunk size at 1. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
get_children iterated the input prefix list directly, so passing the same prefix more than once double-counted its children and inflated utilization counts and percentages. Collect the prefix ids into a set before lookup, restoring the prior dedup semantics. No current caller passes duplicates; this is defensive hardening. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…updates (#9537) Bumps the npm_and_yarn group with 1 update in the /docs directory: [qs](https://github.com/ljharb/qs). Bumps the npm_and_yarn group with 1 update in the /frontend/app directory: [react-router](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router). Updates `qs` from 6.14.2 to 6.15.2 - [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md) - [Commits](ljharb/qs@v6.14.2...v6.15.2) Updates `react-router` from 7.14.2 to 7.15.0 - [Release notes](https://github.com/remix-run/react-router/releases) - [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router/CHANGELOG.md) - [Commits](https://github.com/remix-run/react-router/commits/react-router@7.15.0/packages/react-router) Updates `react-router` from 7.14.2 to 7.15.0 - [Release notes](https://github.com/remix-run/react-router/releases) - [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router/CHANGELOG.md) - [Commits](https://github.com/remix-run/react-router/commits/react-router@7.15.0/packages/react-router) --- updated-dependencies: - dependency-name: qs dependency-version: 6.15.2 dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: react-router dependency-version: 7.15.0 dependency-type: direct:production dependency-group: npm_and_yarn - dependency-name: react-router dependency-version: 7.15.0 dependency-type: direct:production dependency-group: npm_and_yarn ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…date (#9539) Bumps the npm_and_yarn group with 1 update in the /docs directory: [shell-quote](https://github.com/ljharb/shell-quote). Updates `shell-quote` from 1.8.3 to 1.8.4 - [Changelog](https://github.com/ljharb/shell-quote/blob/main/CHANGELOG.md) - [Commits](ljharb/shell-quote@v1.8.3...v1.8.4) Updates `shell-quote` from 1.8.3 to 1.8.4 - [Changelog](https://github.com/ljharb/shell-quote/blob/main/CHANGELOG.md) - [Commits](ljharb/shell-quote@v1.8.3...v1.8.4) --- updated-dependencies: - dependency-name: shell-quote dependency-version: 1.8.4 dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: shell-quote dependency-version: 1.8.4 dependency-type: indirect dependency-group: npm_and_yarn ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
calculate_diff_between_commits labelled a file present only in the new commit as "removed" and one present only in the old commit as "added", inverting the action reported by GET /api/diff/files and the Proposed Change Files tab. The mapping now follows git diff first->second (first=old, second=new). The proposed-change repo-diff caller, which relied on the inverted behaviour via reversed arguments, is corrected to match, and the component test now asserts in the API consumption direction. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
fix: floor computed-attribute chunk size at 1; dedup ipam utilization children
fix(git): correct added/removed file action in repository diffs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Merging stable into release-1.10 after merging pull request #9506.
Summary by cubic
Reduces Git repository lock time by guarding only clone/fetch/worktree mutations and running imports after the lock, cutting contention during syncs and repo creation. Adds an Artifact detail Refresh button, fixes batching and utilization issues, and corrects repository diff file actions.
Bug Fixes
create_commit_worktreeraisesCommitNotFoundError;InfrahubRepository.initfetches a missing commit under the repo lock, then retries.GET /api/diff/filesand the Proposed Change Files tab.Refactors
infrahub/git/sync.pywithRepositorySyncer,RepositoryAdder,RepositoryImporter, andRepositoryFileImporter; introducedPendingObjectImport.InfrahubRepository.syncintocollect_pending_imports(locked) and a separate import phase; tasks use these components.RecordingLockRegistry,LockTimeline,RecordingImporter) and tests to assert lock scope; updated testing docs.react-routerto7.17.0,qsto6.15.2,shell-quoteto1.8.4, plus existing docs/frontend updates (e.g.,vite,postcss,ws).Written for commit a6eb1a7. Summary will update on new commits.