Merge last changes from release-1.11 to develop - #10346
Conversation
prep release 1.10.9
prep release 1.11.0
…ig overrides
`memory_cache` and `bus_simulator` each set a `config.OVERRIDE` field and never
put it back. The `dependency_provider.scope(...)` unwinds on teardown, but
`build_cache()` and `build_message_bus()` consult `config.OVERRIDE` *first*, so
the override outlives the class that installed it and every later resolution in
that xdist worker gets the previous class's throwaway adapter.
For the cache that surfaces as
ResourceNotFoundError: Diff summary for pipeline <uuid> was not found in the cache
in `TestProposedChange::test_run_generators_validate_requested_jobs`. The test
writes the diff summary through a cache built from `config.SETTINGS.cache.driver`
(Redis) and `run_generators` reads it back via `get_cache()`. Once the override
leaks, the write goes to Redis and the read goes to the leftover MemoryCache.
It reads as flaky but it is scheduling: it fails exactly when xdist puts
`test_artifact_regen_e2e.py`, which uses `memory_cache`, on the same worker
earlier in the session. Runs 32238651760 and 32153198842 had both files on gw3
and failed; run 32251034448 had them on gw3 and gw1 and passed.
For the message bus nothing fails today — a stale BusSimulator swallows messages
instead of raising — so it is fixed here before it costs a debugging session.
Save and restore in a `finally`, matching the neighbouring `workflow_local`
fixture and every other override site in the suite.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…class `setup_task_manager_once` recorded only success, so a Prefect test server that came up and then stopped responding was retried by every later test class in that xdist worker. The retry is not cheap. The setup does not fail fast against an unreachable server — it blocks on the API until the pytest timeout fires — so each retry cost the full 300s. In run 32238651760 that turned one broken worker into 46 `Failed: Timeout >300.0s` errors across five test files and pushed the session into its 1800s limit, with the original httpx.ReadTimeout buried under 45 identical copies. Remember the failure alongside the success and re-raise it, chained, on every later call. The worker still fails, but once, in seconds, with the cause attached to the first error rather than the forty-sixth. `except BaseException` is deliberate: the pytest timeout raises `Failed`, which does not derive from `Exception`, and that is exactly the failure worth remembering. The once-per-process state moves onto a `TaskManagerSetup` object that takes the setup callable as a constructor argument, so the tests drive it with recording and failing doubles instead of patching the module — the adapter pattern the testing guidelines ask for. `setup_task_manager_once()` keeps its signature and callers. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…10306) * fix(graphql): reject user-supplied branched_from on branch creation BranchCreate persisted a client-supplied branched_from verbatim, letting a new branch appear to have been created in the past and expose data since deleted on all branches. The mutation now rejects the field with an error, and both branched_from and origin_branch (already restricted to the default branch) are marked deprecated on BranchCreateInput. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * chore(frontend): revert spurious gql.tada cache reorder The @deprecated directives added to BranchCreateInput do not change any document type, so graphql-cache.d.ts should not have been touched. The committed version only reordered entries, which no longer matches what `pnpm codegen:graphql` emits, failing frontend-validate-graphql-types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(graphql): reject empty branched_from and raise ValidationError Addresses cubic review feedback on #10306. A supplied-but-falsy `branched_from` (empty string) slipped past the truthiness check and blew up later as `TimestampFormatError: Invalid time format for ` inside the branch-create flow. Check for presence of a non-null value instead, so every client-supplied value is rejected up front. An explicit `null` is still accepted: it is equivalent to omitting the field and rejecting it would break clients that serialize None. Raise `ValidationError` (HTTP 422, centrally handled) rather than a bare `ValueError`, matching how the rest of this mutation reports invalid input. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(graphql): close the same falsy-input hole for origin_branch `origin_branch: ""` passed the truthiness guard and then overrode the "main" default on the model, producing a branch whose origin_branch is empty. Compare against a non-null value so any supplied value other than the default branch is rejected, and raise ValidationError to match how the neighbouring branched_from check reports invalid input. An explicit null on an optional field previously reached the pydantic model and failed to validate against a non-optional default (origin_branch, description, sync_with_git). Drop nulls when building the model so an explicit null behaves like omitting the field. Rework the BranchCreate input tests onto the dataclass parametrize pattern, covering both rejected fields and the omitted/null fallbacks. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * add removal version --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…aw TCP probe Every rabbitmq-diagnostics invocation boots a full Erlang VM, costing ~2.1s of CPU time per check (measured on rabbitmq:4.2.1-management). At the 1s healthcheck interval this pegs more than two cores per broker container for the entire life of the stack, and the ~0.3-1s wall time races against the 1s timeout on loaded CI machines. check_port_connectivity only verifies that the listener ports accept TCP connections, so a bash /dev/tcp probe on 5672 provides the identical readiness signal at ~1ms per check, with no broker log noise (RabbitMQ does not log connections closed before the protocol header). Exec form is required because the image's /bin/sh (dash) lacks /dev/tcp support. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rocess-wide The configured_logging fixture called configure_logging(production=False, log_level="DEBUG"). That routine is application startup code: it sets the root log level, replaces the root handler and reconfigures structlog, and undoes none of it. Called per test it left the root logger at DEBUG for the rest of the xdist worker, overriding the WARNING level pytest_configure pins, so every later test in that worker logged a line per Bolt message from the Neo4j driver. Install only what the assertions need instead: extract the filter installation from configure_logging as install_traceback_suppression_filter, call that from the fixture and remove the filter after the yield. The fixture is renamed traceback_suppression_installed to say what it now does. Also record the general rule in the backend testing guidelines and the Python testing agent rules: leave process-global state as you found it, and never call an application startup routine from a test. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…logging state The three suppression tests pass whether the fixture installs only the filter or calls configure_logging, since that routine installs the same filter — nothing committed distinguished them, so the leak could come back unnoticed. Extract the fixture body into a _traceback_suppression context manager and assert its contract directly: the Prefect run loggers carry exactly the filter it installed while it is open, and both their filter lists and the root log level are back to their previous values once it closes. Driving the context manager rather than probing state from a later test module keeps the guard hermetic — no dependence on collection order or on which xdist worker picks the file up. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…n loggers Extracting install_traceback_suppression_filter left the configure_logging call site uncovered: dropping it would keep every traceback suppression test passing, since they install the filter themselves. Assert instead on what importing infrahub.log already did — its module-level configure_logging call is the production wiring — so the call site is covered without a test reconfiguring logging for the rest of the worker. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A docstring should say what the test asserts, not what it deliberately does not do. The paragraph explaining why the test reads the state left by the import rather than calling configure_logging again is a note on a choice already made; the rule it follows is written down in the backend testing guidelines. The first line still explains why asserting on import-time state is the wiring assertion, which is the part a reader needs. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
test_traceback_suppression_leaves_logging_state_unchanged drives a context manager and reads logging state — it needs no database, no Prefect flow run and none of the component suite's fixtures, so it belongs next to the other infrahub.log tests in the unit suite. Move the install/remove cycle it drives to tests/helpers/log.py as traceback_suppression, so the webhook fixture and the guard share one implementation across suites and any future fixture that installs the filter inherits the guard. Its docstring keeps the line that says what it does; the paragraph on why it installs the filter alone rather than calling configure_logging is the rule the testing guidelines now carry, which the guidelines point at the helper for. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…nting `read_flow_runs()` returns at most 200 rows (the Prefect API's default page size, and the API rejects a larger limit), so once the session's webhook-process runs fill that page the render test's before/after count comparison saturates at 200 and can never be true again. That makes the test fail deterministically whenever `TestWebhookConfigure` lands on the same xdist worker, which is how five unrelated PRs went red between Aug 13 and Aug 18 with a message blaming server-side parameter rendering. Identify the run by its id and webhook instead, and assert the rendered parameters really are the plain strings the test exists to guard. Delete the webhook automations a test class registers at its teardown: the Prefect server is session-scoped, so a surviving all-branches automation turned every event emitted by every later test in the worker into a scheduled webhook-process run that no worker ever executes. Measured over the webhook package plus one event-heavy ipam class: 216-243 leftover runs and 233-235s without the cleanup, 1 run and 182-201s with it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The v1.10.7 release failed in publish-docker-image / sbom (run
31521732131) when `cosign attest` could not write to the Sigstore
transparency log:
Post "https://rekor.sigstore.dev/api/v1/log/entries":
giving up after 2 attempt(s)
Rekor was only briefly unavailable — the sign job had succeeded against
the same infrastructure five minutes earlier, and the identical sbom job
passed on the next nightly run with no code change. But cosign retries a
failed log write only twice internally and exposes no knob to raise
that, so a blip that short was enough to fail the release. The fallout
was disproportionate: the SBOM upload step never ran, so v1.10.7 is the
only release since v1.10.0 with no SBOM artifacts, and
repository-dispatch (which needs publish-docker-image) was skipped, so
downstream repos were never notified of the release.
Three changes:
- Wrap cosign sign and both cosign attest calls in a retry() helper:
five attempts 60 seconds apart, covering a ~4-minute outage. The
helper takes the command as arguments ("$@", no string/eval layer)
and is pasted verbatim into the sign and sbom jobs — they run on
separate runners, so it cannot be shared without a checkout or a
third-party action in the signing path.
- Upload the SBOM artifacts before attesting them, so a
transparency-log outage can no longer cost us the SBOMs themselves.
Attestation failures still fail the job, which is the correct outcome
for a supply-chain step.
- Set overwrite: true on the SBOM upload. Artifacts are scoped to the
run rather than the attempt, so with the upload now preceding a step
that can fail, a re-run would otherwise die at the upload step
because the artifact name already exists from the earlier attempt.
Every caller passes a version unique to its invocation, so the only
artifact this can replace is the same SBOM from a previous attempt of
the same run.
Verified by extracting both run scripts from the parsed workflow and
executing them against a stubbed cosign: immediate success (1 call, no
sleeps), recovery after 3 failures (exit 0, 3 sleeps), budget
exhaustion (5 calls, 4 sleeps, exit 1), and a terminally failing first
attest stops the script before the second attest runs. The two retry()
bodies are asserted byte-identical, and actionlint passes.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…10336) Bumps the uv group with 5 updates in the / directory: | Package | From | To | | --- | --- | --- | | [pydantic-settings](https://github.com/pydantic/pydantic-settings) | `2.14.1` | `2.14.2` | | [python-multipart](https://github.com/Kludex/python-multipart) | `0.0.27` | `0.0.31` | | [pyjwt](https://github.com/jpadilla/pyjwt) | `2.12.1` | `2.13.0` | | [cryptography](https://github.com/pyca/cryptography) | `48.0.0` | `50.0.0` | | [starlette](https://github.com/Kludex/starlette) | `1.2.1` | `1.3.1` | Bumps the uv group with 2 updates in the /python_testcontainers directory: [pydantic-settings](https://github.com/pydantic/pydantic-settings) and [starlette](https://github.com/Kludex/starlette). Updates `pydantic-settings` from 2.14.1 to 2.14.2 - [Release notes](https://github.com/pydantic/pydantic-settings/releases) - [Commits](pydantic/pydantic-settings@v2.14.1...v2.14.2) Updates `python-multipart` from 0.0.27 to 0.0.31 - [Release notes](https://github.com/Kludex/python-multipart/releases) - [Changelog](https://github.com/Kludex/python-multipart/blob/main/CHANGELOG.md) - [Commits](Kludex/python-multipart@0.0.27...0.0.31) Updates `pyjwt` from 2.12.1 to 2.13.0 - [Release notes](https://github.com/jpadilla/pyjwt/releases) - [Changelog](https://github.com/jpadilla/pyjwt/blob/master/CHANGELOG.rst) - [Commits](jpadilla/pyjwt@2.12.1...2.13.0) Updates `cryptography` from 48.0.0 to 50.0.0 - [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst) - [Commits](pyca/cryptography@48.0.0...50.0.0) Updates `starlette` from 1.2.1 to 1.3.1 - [Release notes](https://github.com/Kludex/starlette/releases) - [Changelog](https://github.com/Kludex/starlette/blob/main/docs/release-notes.md) - [Commits](Kludex/starlette@1.2.1...1.3.1) Updates `pydantic-settings` from 2.12.0 to 2.14.2 - [Release notes](https://github.com/pydantic/pydantic-settings/releases) - [Commits](pydantic/pydantic-settings@v2.14.1...v2.14.2) Updates `starlette` from 1.2.1 to 1.3.1 - [Release notes](https://github.com/Kludex/starlette/releases) - [Changelog](https://github.com/Kludex/starlette/blob/main/docs/release-notes.md) - [Commits](Kludex/starlette@1.2.1...1.3.1) --- updated-dependencies: - dependency-name: pydantic-settings dependency-version: 2.14.2 dependency-type: direct:production dependency-group: uv - dependency-name: python-multipart dependency-version: 0.0.31 dependency-type: direct:production dependency-group: uv - dependency-name: pyjwt dependency-version: 2.13.0 dependency-type: direct:production dependency-group: uv - dependency-name: cryptography dependency-version: 50.0.0 dependency-type: indirect dependency-group: uv - dependency-name: starlette dependency-version: 1.3.1 dependency-type: indirect dependency-group: uv - dependency-name: pydantic-settings dependency-version: 2.14.2 dependency-type: indirect dependency-group: uv - dependency-name: starlette dependency-version: 1.3.1 dependency-type: indirect dependency-group: uv ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Merge stable into release-1.11
Adds a skill that mines GitHub Actions history for flaky tests using retry outcomes (failed attempt -> green re-run) and cross-PR recurrence as evidence. A bundled stdlib-only collector caches runs, failed-job logs, and a longitudinal per-test ledger under ~/ci-cache so successive invocations build trend data instead of re-querying the GitHub API. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Split main() into focused helpers, use set.update over add-in-loop, escape the Playwright breadcrumb separator, and add explicit encodings. Verified against the release-1.11 window: identical results (180 runs matched, 38 failed jobs) and idempotent ledger. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Split date-range queries: the Actions runs API silently caps listings at 1000 results; the first pass over a 1321-run week dropped the oldest 321 runs. - Extract Playwright tests from hyphenated project names (e.g. [docs-regression-check]). - New systemic buckets: runner-oom (exit 137), docker network pool exhaustion, actions-download 429, and green-pytest-exit-1 (session-teardown abort after all tests pass). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
An expired log wrote an empty file via gh(..., check=False), and the st_size == 0 branch re-fetched it on every collection, defeating the documented never-re-download guarantee. Downloads now distinguish HTTP 404/410 (log gone: durable empty sentinel, never re-fetched) from transient gh failures (no file written, warned, retried next run), so the download condition is a plain exists() check. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The sqlite-locked bucket regex only matched the SQLAlchemy-wrapped form `(sqlite3.OperationalError) database is locked` while the SKILL.md table documented the raw `sqlite3.OperationalError:` form. In every cached incident log both renderings appear together (chained traceback), so the bucket did tag, but a raw-only occurrence is plausible. Match both via `[):]` and sync the SKILL.md table with the code. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The BUCKETS comment and SKILL.md Step 4 promised that a systemic cascade is reported as one incident, but report-data.json only annotated per-test entries with bucket tags — the analyst had to derive incident counts by hand from failed_jobs_with_tests.json. The report now carries bucket_incidents (distinct jobs/runs/PRs per bucket), the BUCKETS comment describes the actual mechanism (tags feed the incident counts and the Step 4 judgment), and SKILL.md points at the new field. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A zero-byte body on a successful logs API call would have written the same empty file the expired-log (404/410) sentinel uses, permanently suppressing retries for that job. A real job log is never empty, so leave the file unwritten and warn instead; the next collection retries. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Running the skill no longer triggers a Bash permission prompt for the bundled collect.py invocation. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Merge stable into release-1.11
There was a problem hiding this comment.
6 issues found across 31 files
Confidence score: 2/5
backend/infrahub/graphql/mutations/branch.pycan create branches from the literalmaininstead of the configured default whenorigin_branchis omitted or null, causing schema mismatches or failed creation; align the model default with the configured branch..agents/skills/analyzing-ci-flakiness/scripts/collect.pycan silently omit runs after GitHub rejects a commit lookup, and it redownloads identical job logs across overlapping windows, making collection both incomplete and inefficient; propagate or surface lookup failures and reuse cached job IDs/logs..github/workflows/ci-docker-image.ymlcan overwrite the first SBOM artifact when a reusable workflow is invoked multiple times without distinct versions, losing build output; require a unique invocation key or incorporate the invocation identity into the artifact name.python_sdkis pinned to a stable release lineage rather than the requiredorigin/develop, while the security dependency updates inpyproject.tomlappear to need the project's towncrier release metadata; correct the submodule ref and add the required release note fragments.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name=".github/workflows/ci-docker-image.yml">
<violation number="1" location=".github/workflows/ci-docker-image.yml:281">
P2: When this reusable workflow runs twice in one caller run with an omitted or reused `version`, `overwrite: true` silently replaces the first invocation’s SBOM artifact. Require a unique invocation key or include the image digest/job identity in the artifact name while retaining overwrite for reruns.</violation>
</file>
<file name="pyproject.toml">
<violation number="1" location="pyproject.toml:48">
P3: These dependency bumps are security patches (python-multipart fixes a multipart DoS; pyjwt 2.13.0 is a security release) that user-visible behavior on uploads and JWT handling. Per the project's towncrier convention for dependency/security changes, add a `changelog/<issue-id>.security.md` fragment so the next release notes and CHANGELOG.md capture these fixes. Neither changelog/ nor CHANGELOG.md currently references them, so they would silently drop out of the release notes when develop next ships.</violation>
</file>
<file name="backend/infrahub/graphql/mutations/branch.py">
<violation number="1" location="backend/infrahub/graphql/mutations/branch.py:100">
P1: When the configured default branch is not `main`, omitting `origin_branch` or sending `null` still constructs the model with `origin_branch="main"`, so branch creation uses the wrong schema or fails. Set the model's `origin_branch` to `registry.default_branch` before dispatching the workflow.</violation>
</file>
<file name=".agents/skills/analyzing-ci-flakiness/scripts/collect.py">
<violation number="1" location=".agents/skills/analyzing-ci-flakiness/scripts/collect.py:156">
P1: When GitHub rate-limits or rejects a PR commit lookup, `check=False` turns the failure into an empty SHA set and the collector silently drops that PR's runs. Propagate the error or emit a warning and mark collection incomplete; do not treat an API failure as a PR with no commits.</violation>
<violation number="2" location=".agents/skills/analyzing-ci-flakiness/scripts/collect.py:245">
P2: On successive overlapping windows, `collect_failed_jobs` looks only under the current window, so the same job log is downloaded again. Put job logs in a repository-level cache or resolve an existing job ID from prior windows before calling `fetch_job_log`.</violation>
</file>
<file name="python_sdk">
<violation number="1" location="python_sdk:1">
P2: This merge to develop bumps the python_sdk submodule to 99a380ac (tag v1.23.0, merge of "prep-release-1.23.0"), which sits on the stable/release lineage. Per AGENTS.md, the develop branch must pin python_sdk to origin/infrahub-develop, whose head is currently 5a25f46; neither 99a380ac nor the tip commit 2c853c0 is an ancestor of infrahub-develop. After this release merge lands on develop, re-pin the submodule to origin/infrahub-develop.</violation>
</file>
Shadow auto-approve: would not auto-approve because issues were found.
Re-trigger cubic
| task: dict | None = None | ||
|
|
||
| model = BranchCreateModel(**data) | ||
| model = BranchCreateModel(**{key: value for key, value in data.items() if value is not None}) |
There was a problem hiding this comment.
P1: When the configured default branch is not main, omitting origin_branch or sending null still constructs the model with origin_branch="main", so branch creation uses the wrong schema or fails. Set the model's origin_branch to registry.default_branch before dispatching the workflow.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At backend/infrahub/graphql/mutations/branch.py, line 100:
<comment>When the configured default branch is not `main`, omitting `origin_branch` or sending `null` still constructs the model with `origin_branch="main"`, so branch creation uses the wrong schema or fails. Set the model's `origin_branch` to `registry.default_branch` before dispatching the workflow.</comment>
<file context>
@@ -77,13 +86,18 @@ async def mutate(
task: dict | None = None
- model = BranchCreateModel(**data)
+ model = BranchCreateModel(**{key: value for key, value in data.items() if value is not None})
await apply_external_context(graphql_context=graphql_context, context_input=context)
</file context>
| model = BranchCreateModel(**{key: value for key, value in data.items() if value is not None}) | |
| model_data = {key: value for key, value in data.items() if value is not None} | |
| model_data["origin_branch"] = registry.default_branch | |
| model = BranchCreateModel(**model_data) |
| def pr_head_shas(repo: str, numbers: list[int]) -> dict[str, set[int]]: | ||
| sha2pr: dict[str, set[int]] = defaultdict(set) | ||
| for n in numbers: | ||
| out = gh(["api", f"repos/{repo}/pulls/{n}/commits?per_page=100", "--paginate", "--jq", ".[].sha"], check=False) |
There was a problem hiding this comment.
P1: When GitHub rate-limits or rejects a PR commit lookup, check=False turns the failure into an empty SHA set and the collector silently drops that PR's runs. Propagate the error or emit a warning and mark collection incomplete; do not treat an API failure as a PR with no commits.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .agents/skills/analyzing-ci-flakiness/scripts/collect.py, line 156:
<comment>When GitHub rate-limits or rejects a PR commit lookup, `check=False` turns the failure into an empty SHA set and the collector silently drops that PR's runs. Propagate the error or emit a warning and mark collection incomplete; do not treat an API failure as a PR with no commits.</comment>
<file context>
@@ -0,0 +1,410 @@
+def pr_head_shas(repo: str, numbers: list[int]) -> dict[str, set[int]]:
+ sha2pr: dict[str, set[int]] = defaultdict(set)
+ for n in numbers:
+ out = gh(["api", f"repos/{repo}/pulls/{n}/commits?per_page=100", "--paginate", "--jq", ".[].sha"], check=False)
+ for sha in out.split():
+ sha2pr[sha].add(n)
</file context>
| infrahub-sbom.spdx.json | ||
| infrahub-sbom.cdx.json | ||
| retention-days: 90 | ||
| overwrite: true |
There was a problem hiding this comment.
P2: When this reusable workflow runs twice in one caller run with an omitted or reused version, overwrite: true silently replaces the first invocation’s SBOM artifact. Require a unique invocation key or include the image digest/job identity in the artifact name while retaining overwrite for reruns.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/ci-docker-image.yml, line 281:
<comment>When this reusable workflow runs twice in one caller run with an omitted or reused `version`, `overwrite: true` silently replaces the first invocation’s SBOM artifact. Require a unique invocation key or include the image digest/job identity in the artifact name while retaining overwrite for reruns.</comment>
<file context>
@@ -258,3 +278,37 @@ jobs:
infrahub-sbom.spdx.json
infrahub-sbom.cdx.json
retention-days: 90
+ overwrite: true
+
+ - name: Attest SBOMs
</file context>
| print(f"[collect] WARN jobs {r['id']}/{attempt}: {exc}", file=sys.stderr) | ||
| continue | ||
| for job in jobs: | ||
| log_path = win_dir / "joblogs" / f"{job['id']}.log" |
There was a problem hiding this comment.
P2: On successive overlapping windows, collect_failed_jobs looks only under the current window, so the same job log is downloaded again. Put job logs in a repository-level cache or resolve an existing job ID from prior windows before calling fetch_job_log.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .agents/skills/analyzing-ci-flakiness/scripts/collect.py, line 245:
<comment>On successive overlapping windows, `collect_failed_jobs` looks only under the current window, so the same job log is downloaded again. Put job logs in a repository-level cache or resolve an existing job ID from prior windows before calling `fetch_job_log`.</comment>
<file context>
@@ -0,0 +1,410 @@
+ print(f"[collect] WARN jobs {r['id']}/{attempt}: {exc}", file=sys.stderr)
+ continue
+ for job in jobs:
+ log_path = win_dir / "joblogs" / f"{job['id']}.log"
+ if not log_path.exists():
+ fetch_job_log(repo, job["id"], log_path)
</file context>
| @@ -1 +1 @@ | |||
| Subproject commit f9e28cfd5958946759f113fd9fe29422adc8fcea | |||
| Subproject commit 99a380ac145cb549687bc2b8030cf5edf2f5a492 | |||
There was a problem hiding this comment.
P2: This merge to develop bumps the python_sdk submodule to 99a380ac (tag v1.23.0, merge of "prep-release-1.23.0"), which sits on the stable/release lineage. Per AGENTS.md, the develop branch must pin python_sdk to origin/infrahub-develop, whose head is currently 5a25f46; neither 99a380ac nor the tip commit 2c853c0 is an ancestor of infrahub-develop. After this release merge lands on develop, re-pin the submodule to origin/infrahub-develop.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At python_sdk, line 1:
<comment>This merge to develop bumps the python_sdk submodule to 99a380ac (tag v1.23.0, merge of "prep-release-1.23.0"), which sits on the stable/release lineage. Per AGENTS.md, the develop branch must pin python_sdk to origin/infrahub-develop, whose head is currently 5a25f46; neither 99a380ac nor the tip commit 2c853c0 is an ancestor of infrahub-develop. After this release merge lands on develop, re-pin the submodule to origin/infrahub-develop.</comment>
<file context>
@@ -1 +1 @@
-Subproject commit f9e28cfd5958946759f113fd9fe29422adc8fcea
+Subproject commit 99a380ac145cb549687bc2b8030cf5edf2f5a492
</file context>
| "starlette-exporter>=0.23,<0.24", | ||
| "prometheus-client>=0.25,<0.26", | ||
| "python-multipart==0.0.27", # Required by FastAPI to upload large files | ||
| "python-multipart==0.0.31", # Required by FastAPI to upload large files |
There was a problem hiding this comment.
P3: These dependency bumps are security patches (python-multipart fixes a multipart DoS; pyjwt 2.13.0 is a security release) that user-visible behavior on uploads and JWT handling. Per the project's towncrier convention for dependency/security changes, add a changelog/<issue-id>.security.md fragment so the next release notes and CHANGELOG.md capture these fixes. Neither changelog/ nor CHANGELOG.md currently references them, so they would silently drop out of the release notes when develop next ships.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At pyproject.toml, line 48:
<comment>These dependency bumps are security patches (python-multipart fixes a multipart DoS; pyjwt 2.13.0 is a security release) that user-visible behavior on uploads and JWT handling. Per the project's towncrier convention for dependency/security changes, add a `changelog/<issue-id>.security.md` fragment so the next release notes and CHANGELOG.md capture these fixes. Neither changelog/ nor CHANGELOG.md currently references them, so they would silently drop out of the release notes when develop next ships.</comment>
<file context>
@@ -45,10 +45,10 @@ dependencies = [
"starlette-exporter>=0.23,<0.24",
"prometheus-client>=0.25,<0.26",
- "python-multipart==0.0.27", # Required by FastAPI to upload large files
+ "python-multipart==0.0.31", # Required by FastAPI to upload large files
"asgi-correlation-id==4.2.0", # Middleware for FastAPI to generate ID per request
"bcrypt>=4.1,<4.2", # Used to hash and validate password
</file context>
Why
Bring in the last updates from
release-1.11before the git bot starts to targetstabledirectly todevelopReplaces #10343.
What changed
tyhappy: 2c853c0