Skip to content

chore(ci): bump actions/upload-artifact from 4 to 7#28

Open
dependabot[bot] wants to merge 300 commits into
mainfrom
dependabot/github_actions/actions/upload-artifact-7
Open

chore(ci): bump actions/upload-artifact from 4 to 7#28
dependabot[bot] wants to merge 300 commits into
mainfrom
dependabot/github_actions/actions/upload-artifact-7

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Jul 4, 2026

Copy link
Copy Markdown
Contributor

Bumps actions/upload-artifact from 4 to 7.

Release notes

Sourced from actions/upload-artifact's releases.

v7.0.0

v7 What's new

Direct Uploads

Adds support for uploading single files directly (unzipped). Callers can set the new archive parameter to false to skip zipping the file during upload. Right now, we only support single files. The action will fail if the glob passed resolves to multiple files. The name parameter is also ignored with this setting. Instead, the name of the artifact will be the name of the uploaded file.

ESM

To support new versions of the @actions/* packages, we've upgraded the package to ESM.

What's Changed

New Contributors

Full Changelog: actions/upload-artifact@v6...v7.0.0

v6.0.0

v6 - What's new

[!IMPORTANT] actions/upload-artifact@v6 now runs on Node.js 24 (runs.using: node24) and requires a minimum Actions Runner version of 2.327.1. If you are using self-hosted runners, ensure they are updated before upgrading.

Node.js 24

This release updates the runtime to Node.js 24. v5 had preliminary support for Node.js 24, however this action was by default still running on Node.js 20. Now this action by default will run on Node.js 24.

What's Changed

Full Changelog: actions/upload-artifact@v5.0.0...v6.0.0

v5.0.0

What's Changed

BREAKING CHANGE: this update supports Node v24.x. This is not a breaking change per-se but we're treating it as such.

... (truncated)

Commits
  • 043fb46 Merge pull request #797 from actions/yacaovsnc/update-dependency
  • 634250c Include changes in typespec/ts-http-runtime 0.3.5
  • e454baa Readme: bump all the example versions to v7 (#796)
  • 74fad66 Update the readme with direct upload details (#795)
  • bbbca2d Support direct file uploads (#764)
  • 589182c Upgrade the module to ESM and bump dependencies (#762)
  • 47309c9 Merge pull request #754 from actions/Link-/add-proxy-integration-tests
  • 02a8460 Add proxy integration test
  • b7c566a Merge pull request #745 from actions/upload-artifact-v6-release
  • e516bc8 docs: correct description of Node.js 24 support in README
  • Additional commits viewable in compare view

Use per-ingestion identifiers for shard branch names so repeat local or UI runs do not collide on stale Branching names and do not need destructive cleanup to keep moving.

Constraint: branch cleanup must not hide failed or partially merged runs
Rejected: auto-delete stale branches on rerun | that could mask production failures and complicate recovery
Confidence: high
Scope-risk: narrow
Directive: keep any future cleanup logic explicit and failure-aware; branch-name uniqueness should remain the default safety rail
Tested: invoke lint, invoke test, invoke docs
Not-tested: live Branching branch creation in a production NetBox deployment
Pin the remaining lifecycle transitions on sync and merge failure paths, and verify that paginated query fetches keep query IDs and filters attached across every page.

Constraint: keep behavior NetBox-native and avoid silent state drift in merge or fetch error paths
Rejected: broad refactor of state/orchestration modules | the immediate safety gap is better closed by tests and a targeted persistence fix
Confidence: high
Scope-risk: narrow
Directive: future refactors should preserve the persisted failed-state updates and pagination filter propagation
Tested: invoke lint, invoke test, invoke docs
Not-tested: live Forward API pagination against a production tenant
…ilures

Resumed multi-branch runs should not re-run preflight, and snapshot metric
fetches should remain best-effort so a telemetry outage does not block an
otherwise valid ingestion. The tests pin both behaviors in the harness.

Constraint: Forward snapshot metrics are operational metadata, not a hard sync precondition
Rejected: Re-run preflight on resume | it duplicates work and breaks the resume contract
Rejected: Fail ingestion when metrics lookup fails | it turns observability into an outage path
Confidence: high
Scope-risk: narrow
Directive: Do not make snapshot metrics mandatory for ingestion success
Tested: invoke lint; invoke test; invoke ci
Not-tested: live Forward API metrics outage handling
…cution contract pinned

Cable apply/delete logic is now isolated in a dedicated module while the
runner methods remain as compatibility shims. The extraction is backed by
new branch-execution tests and an explicit plan record so the harness keeps
tracking the boundary move.

Constraint: Must preserve the existing cable semantics and public runner API
Rejected: Broad sync-module rewrite | too much blast radius for the current tranche
Confidence: high
Scope-risk: moderate
Directive: Treat remaining sync-module extraction as incremental boundary work
Tested: invoke lint; invoke test; invoke ci
Not-tested: live Branching cleanup against stale production shards
…odule adapter family

Inventory-item and module apply/delete behavior now lives in a dedicated
adapter module, while the runner methods stay as delegation shims so the
existing public behavior and tests remain stable.

Constraint: Preserve module-native inventory cleanup and existing sync semantics
Rejected: Broader sync refactor in the same pass | would widen the blast radius beyond verified coverage
Confidence: high
Scope-risk: moderate
Directive: Keep extracting adapter families one at a time and preserve the runner API until the split is complete
Tested: invoke lint; invoke test; invoke ci
Not-tested: live NetBox branch cleanup after a real overflow retry
Site, manufacturer, platform, device-role, and device-type adapter logic
now lives in a dedicated helper module. The runner API stays intact so the
existing coverage continues to pin behavior while the module boundary moves.

Constraint: Preserve delete and coalesce semantics for core identity models
Rejected: Wider refactor across all remaining sync adapters | too much blast radius for one tranche
Confidence: high
Scope-risk: moderate
Directive: Continue carving out adapter families in small, behavior-preserving steps
Tested: invoke lint; invoke test; invoke ci
Not-tested: live Forward maintenance against a partially merged shard set
Device and virtual chassis apply/delete logic now live in a dedicated helper
module. This preserves the current sync behavior while shrinking the main
sync module further and keeping the split test-backed.

Constraint: Preserve device and virtual chassis semantics while moving code
Rejected: Jump straight to the remaining adapter families | too broad for one tranche
Confidence: high
Scope-risk: moderate
Directive: Keep the sync-module split incremental and behavior-preserving
Tested: invoke lint; invoke test; invoke ci
Not-tested: live NetBox shard cleanup after a real merge handoff
…oints

IPAM and routing/peering entrypoints now live in dedicated helper modules,
while the deeper resolver methods remain in sync.py for a later boundary pass.
This keeps the public runner API stable and trims more of the overgrown sync
module with test-backed delegation shims.

Constraint: Preserve IPAM and routing semantics while moving only the adapter entrypoints
Rejected: Pull the lower-level routing resolvers in the same pass | too broad for a single verified tranche
Confidence: high
Scope-risk: moderate
Directive: Continue extracting sync families incrementally and leave the deeper resolver logic for a later dedicated pass
Tested: invoke lint; invoke test; invoke ci
Not-tested: live Forward validation of a mixed IPAM and routing run after shard retries
Move the interface, MAC address, and feature-tag entrypoints out of the oversized sync runner while leaving the runner API and behavior intact. The extracted module keeps dependency failure handling and LAG/MAC/tag semantics in place, and the architecture notes now reflect the narrower boundary.

Constraint: Preserve public runner methods and NetBox-native behavior
Rejected: Fold this into the earlier cable tranche | keeping each boundary move small is easier to verify and rollback
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Any further sync.py extraction should keep behavior pinned with tests before moving another adapter family
Tested: invoke lint; invoke test; invoke ci
Move the remaining routing helper logic out of the oversized sync runner into the dedicated routing module while keeping the runner API and behavior intact. The runner methods now delegate to the helper module, the architecture notes reflect the new boundary, and the tranche is documented as completed.

Constraint: Preserve public runner methods and NetBox-native branching behavior
Rejected: Fold the routing helpers into the earlier entrypoint-only extraction | the helper boundary was the last coherent routing chunk still embedded in sync.py
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Any later sync.py cleanup should treat the remaining generic helpers as a separate boundary, not part of this routing tranche
Tested: invoke lint; invoke test; invoke ci
Not-tested: live Forward dataset replay after the routing helper move
Refresh the architecture and debt notes so they reflect the current helper/shim split instead of implying the routing extraction is still incomplete. This keeps the follow-up plan honest after the sync boundary work and avoids reopening the same tranche on future passes.

Constraint: Keep the docs aligned with the verified code state
Rejected: Leave the old wording in place | it would overstate remaining adapter-extraction work
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Future refactors should treat the remaining sync.py helpers as a separate generic layer, not as unfinished routing extraction
Tested: invoke ci
Not-tested: none beyond the doc wording change
Move the multi-branch planning boundary into its own module so the executor can keep the runtime state machine focused on branch lifecycle, overflow retry, and merge handoff. The compatibility re-export keeps existing callers and tests working while the new plan boundary is documented and reflected in the architecture notes.

Constraint: Preserve the current planner API for existing tests and UI flows
Rejected: Split the executor in the same pass | the execution/state machine is the riskier boundary and should be handled separately
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Treat later multi_branch.py cleanup as execution-state work, not planner cleanup
Tested: invoke lint; invoke test; invoke ci
Not-tested: live Forward replay after planner extraction
Move the execution state machine into a dedicated module while keeping a compatibility shim at the old import path. That keeps the planner/executor split aligned with the architecture notes and lets later refactors work against a smaller surface.

Constraint: Preserve the existing import surface and branch semantics.
Rejected: Keep planner and executor together in multi_branch.py | would leave the largest execution boundary mixed with planning.
Confidence: high
Scope-risk: moderate
Directive: Future execution-state changes should land in multi_branch_executor.py, not back in the compatibility shim.
Tested: invoke harness-check, invoke lint, invoke test, invoke docs, invoke ci
Not-tested: Live Forward production data or customer-specific sync runs
The refactor keeps branch heartbeats, query diagnostics, and sync facade boundaries split so the same smoke and 0.7 fixes can be mirrored into the release branches without reintroducing the old monolith.

Constraint: live smoke run is still active; avoid altering runtime environment or customer data
Rejected: split the work into many tiny commits | the branch transplant is easier to review and cherry-pick as one cohesive unit
Confidence: high
Scope-risk: broad
Directive: future branch ports should mirror the exact tested boundary set; avoid reintroducing logic into sync.py/models.py unless a regression demands it
Tested: prior invoke ci/lint/test/docs gates on the refactor; live ADP smoke is currently progressing under the heartbeat path
Not-tested: post-commit branch cherry-picks still need verification on 4.6 and turbobulk worktrees
The completed plan notes needed the standard Approach and Rollback sections (and the IPAM tranche also needed Touched Surfaces) so the pre-push harness would accept the 0.7 branch cleanup. This is a documentation-only fix to keep the release gate honest without changing any runtime behavior.

Constraint: the repo's push gate rejects completed plan notes that omit required headings
Rejected: bypass the gate | that would leave the release workflow inconsistent with the repo contract
Confidence: high
Scope-risk: narrow
Directive: finished plan notes should always include the required structural headings before they are considered release-ready
Tested: document-only change; the files were validated by the pre-push harness on the previous push attempt
Not-tested: runtime code paths were not changed
The pre-push gate surfaced a small amount of doc formatting and import-order drift after the 0.7 transplant and plan-heading fixes. This commit folds that mechanical cleanup back into the main line so the branch is clean, lintable, and ready to push.

Constraint: the repository pre-push gate must run against a clean main tree
Rejected: leave the formatter drift uncommitted | that would just fail the next push attempt again
Confidence: high
Scope-risk: narrow
Directive: if the gate rewrites files, commit the resulting mechanical change before retrying the push
Tested: invoke lint (post-hook cleanup; one import-order rewrite was applied)
Not-tested: invoke test/docs/ci were not rerun after this mechanical cleanup
The 0.7 refactor has been validated, the release docs now point at the new artifact, and the release plan records the remaining publishing steps. The package metadata and plugin version are bumped together so the tagged release, GitHub assets, and PyPI upload can all reference the same version.

Constraint: release metadata, install examples, and release notes must match the tagged artifact
Rejected: publish from an unbumped tree | that would make the GitHub and PyPI artifacts disagree with the repository docs
Confidence: high
Scope-risk: moderate
Directive: if a later patch release is needed, bump the version first and keep the docs synchronized before tagging
Tested: invoke ci
Not-tested: git tag, GitHub release creation, and PyPI upload remain to be executed
The release plan was moved out of active tracking once v0.7.0 was published on GitHub and PyPI.

Constraint: keep plan artifacts aligned with actual release state
Rejected: leave the plan in active/ | it no longer reflected the current state
Confidence: high
Scope-risk: narrow
Directive: future release plans should be moved to completed/ once the tag and package are published
Tested: file move only; no code-path change
Not-tested: none
A local release validation rebuild killed a long-running shard while leaving branch-run state in the database. The activity display now distinguishes fresh shard heartbeats from stale progress so operators do not mistake a dead worker for active row processing.

Constraint: stale heartbeat detection must not mutate sync state or delete Branching branches
Rejected: auto-fail stale syncs | timestamp staleness alone is not enough proof for production state mutation
Rejected: automatic branch cleanup | stale branches are useful failure evidence and cleanup can hide partial runs
Confidence: high
Scope-risk: narrow
Directive: do not turn stale progress display into automatic recovery without a dedicated branch-cleanup plan
Tested: invoke lint; docker exec forward-netbox-netbox-1 python manage.py test --keepdb --noinput forward_netbox.tests.test_sync_state; invoke docs
Not-tested: full invoke ci, to avoid recreating the local NetBox container during smoke rerun setup
NetBox rejects cables attached to interfaces represented as native LAGs. A prior cable import can therefore make a later interface shard fail when Forward now identifies the endpoint as an aggregate interface.

The cable query now excludes aggregate endpoints on both sides, and the interface adapter removes an existing cable inside the active branch before converting that interface to type lag. This keeps the remediation inside normal NetBox object operations and avoids requiring manual cleanup before sync.

Constraint: NetBox disallows cables on Link Aggregation Group interfaces

Rejected: Require operators to manually remove conflicting cables | this blocks otherwise valid shard execution

Rejected: Continue importing aggregate endpoint links as cables | this violates the NetBox interface model

Confidence: high

Scope-risk: narrow

Directive: Do not re-enable cables on aggregate endpoints without validating NetBox LAG invariants

Tested: Targeted NetBox tests for LAG membership, cross-shard LAG placeholders, cable removal before LAG conversion, and inferred cable query aggregate filters

Tested: invoke lint

Tested: invoke harness-check

Not-tested: Full live all-maps smoke sync after this fix
The 0.7.0 line stayed healthy overnight, but the cable ingestion fix and the follow-up retry/re-planning hardening belong on the supported release line. This commit bumps the package/plugin version, updates the user-facing release tables, and records the NQE preflight hardening work as completed.

Constraint: GitHub and PyPI releases must be immutable and release from a verified tagged commit.
Rejected: Republish 0.7.0 | immutable artifacts and release history would become misleading.
Confidence: high
Scope-risk: moderate
Directive: Keep the 0.7.x line pinned to NetBox 4.5.x until a separate compatibility pass says otherwise.
Tested: invoke ci
Not-tested: GitHub tag CI and publication artifacts until the tag is pushed
Large initial syncs can exceed practical Branching review and runtime budgets, so this adds an opt-in execution backend that reuses the existing NQE, validation, row-adapter, and ingestion reporting contracts while writing directly to NetBox for trusted baseline loads. Branching remains the default path for reviewable steady-state syncs.

Constraint: NetBox Branching remains the default reviewable workflow
Constraint: NQE remains the row normalization source of truth
Rejected: Separate importer command | would bypass the normal Sync UI/API validation and reporting workflow
Rejected: Fast bootstrap as default | removes review branches from normal steady-state syncs
Confidence: high
Scope-risk: moderate
Directive: Keep fast bootstrap sharing ForwardQueryFetcher, ForwardValidationRunner, and ForwardSyncRunner adapters; do not fork model normalization into Python
Tested: invoke sensitive-check
Tested: invoke harness-check
Tested: invoke docs
Tested: invoke ci
Tested: clean local bounded fast-bootstrap smoke against live large dataset
Not-tested: full all-model fast-bootstrap completion after dcim.cable on a clean database
The release has been tagged, validated, and published, so move the plan out of active and record the external publication evidence.

Constraint: Release artifacts are immutable after GitHub and PyPI publication
Confidence: high
Scope-risk: narrow
Tested: invoke sensitive-check
Tested: invoke harness-check
Tested: invoke docs
Not-tested: Full invoke ci because this is documentation-only release-plan hygiene
Operators need one place to choose between the reviewable Branching baseline and the trusted fast-bootstrap baseline, so the docs now include an explicit decision table and point the README and usage workflow to it.

Constraint: Documentation must keep Branching as the default steady-state workflow
Confidence: high
Scope-risk: narrow
Tested: invoke sensitive-check
Tested: invoke harness-check
Tested: invoke docs
Not-tested: Full invoke ci because this is documentation-only guidance
Fast bootstrap writes directly to NetBox, so it needs native request tracking and ObjectChange-backed counters to avoid looking like a dry run. The release also carries runtime timeout guidance and transient Forward API retry handling for intermittent sync-start gateway/timeouts.

Constraint: Keep Branching as the default reviewable backend

Constraint: Fast bootstrap remains branchless for trusted initial baselines

Rejected: Synthetic Branching diffs for fast bootstrap | direct writes should use NetBox ObjectChange audit records

Confidence: high

Scope-risk: moderate

Directive: Do not remove the fast-bootstrap request id without replacing the branchless ingestion Changes/statistics surface

Tested: invoke ci

Tested: python -m twine check dist/*

Not-tested: Live customer fast-bootstrap sync after package install
NetBox rejects virtual chassis device assignments when vc_position is missing, so the built-in Forward Virtual Chassis map now emits a member position for deterministic MLAG pairs and vPC primary/secondary roles. The same query shape was committed to the Forward org validation library and this patch release documents the corrected contract.

Constraint: Keep the correction in NQE so NetBox receives native dcim.virtualchassis fields

Rejected: Python-side defaulting | the query has better access to Forward HA role and peer ordering

Confidence: high

Scope-risk: narrow

Directive: Do not emit virtual chassis membership rows without vc_position unless NetBox validation requirements change

Tested: invoke ci

Tested: python -m twine check dist/*

Tested: live Forward org NQE query_id returned 1196 rows with zero missing vc_position before release metadata commit

Not-tested: Full customer sync after installing 0.8.1.1
Forward query IDs are org-specific, so large-sync users need a NetBox-native way to bind maps by repository path and, when desired, publish the bundled NQE into the selected source's Org Repository without switching to the Forward UI.

Constraint: Forward Org Repository commits require Network Operator or equivalent NQE-library write permission

Constraint: NQE remains the normalization/source-of-truth layer; NetBox stores native map references

Rejected: Custom binding script or standalone workflow | duplicates NetBox native bulk edit and is harder to audit

Confidence: high

Scope-risk: moderate

Directive: Keep future query-reference changes inside NetBox map forms or native bulk edit unless NetBox cannot express the workflow

Tested: invoke ci

Tested: python -m twine check dist/*

Tested: python scripts/check_sensitive_content.py && git diff --check

Not-tested: Live publish to a real Forward Org Repository
Stale or invalid output from one Forward NQE model should not suppress unrelated later shards such as routing, so this release isolates model failures, rejects positionless virtual-chassis membership before NetBox save, and keeps dirty runs from becoming diff baselines.

Constraint: Keep NQE as the normalization source of truth and do not invent virtual-chassis positions in Python

Constraint: Preserve NetBox-native Branching execution while reducing blast radius from row/model failures

Rejected: Abort all later shards after one model records row issues | suppresses unrelated routing and cabling work

Rejected: Mark dirty runs baseline-ready | subsequent diffs would trust an incomplete import

Confidence: high

Scope-risk: moderate

Directive: Keep future resilience changes visible through model_results and ingestion issues instead of hiding them

Tested: invoke ci

Tested: python -m twine check dist/*

Tested: git diff --check

Not-tested: Full live customer sync after installing 0.8.3
Forward HA peer data describes vPC, MLAG, and active/standby control-plane relationships, not native NetBox virtual chassis membership. The built-in virtual chassis map is now conservative by default while custom maps can still emit true virtual chassis rows.

The Forward repository query lookup now tolerates list-style responses from the committed-query endpoint so publishing and repository-path sync resolution use the exact requested query path.

Constraint: Keep NQE as the source of truth for model classification

Rejected: Map vPC or MLAG peers to dcim.virtualchassis | those are dual-control-plane HA constructs

Confidence: high

Scope-risk: moderate

Directive: Do not re-enable HA-peer virtual chassis mapping without proving the Forward source represents shared-control-plane chassis membership

Tested: invoke sensitive-check; invoke ci; python -m twine check dist/*; live repository query hash match and zero-row execution

Not-tested: Customer production sync after package upgrade
The field report showed a failed sync still presenting the last module row heartbeat, which made the operator think routing was the failing surface even though the run had not reached routing. Retarget the release to 0.8.4 because this now includes an operator-visible progress-state correction alongside the virtual-chassis and repository-query compatibility fixes. Clear row heartbeat fields when execution advances phases and mark branch-run state failed when orchestration catches a terminal sync exception.

Constraint: Keep NQE as the source of truth and preserve NetBox-native sync state surfaces.

Rejected: Publishing this as 0.8.3.1 | the progress visibility fix is large enough to warrant 0.8.4.

Confidence: high

Scope-risk: moderate

Directive: Do not surface stale row heartbeat text after a phase transition or terminal sync failure.

Tested: invoke ci; python -m twine check dist/forward_netbox-0.8.4*; targeted sync_state, sync_orchestration, virtual-chassis, query-registry, and Forward API tests
captainpacket and others added 13 commits July 4, 2026 06:57
CODEOWNERS with global + high-risk-path owners (placeholder team slug the
maintainer sets to the real team). Updated the enterprise/GA roadmap register to
reflect the tier-2 items landed this session (prune-by-PK, SaaS rpm clamp, retry
jitter/Retry-After) and the residual that requires a decision, a design cycle, or
absent tooling.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Closes the remaining documentation/supply-chain GA items from the assessment:
- docs/02_Reference/rest-api.md — plugin REST endpoints + custom actions.
- docs/01_User_Guide/versioning.md — SemVer + a concrete deprecation process.
- release.yml — CycloneDX SBOM over declared runtime deps, published as its own
  artifact (kept out of the PyPI dist/ upload).

Docs + release pipeline only; mkdocs --strict / lint / harness pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Closes the observability gap: a stuck-job detector existed (job_liveness, 180s
heartbeat) but nothing surfaced a wedged sync autonomously. The new command scans
forward_netbox jobs that are DB-active (PENDING/RUNNING) but have no live RQ
execution, prints a JSON report, warns, and exits non-zero with --fail-on-stuck so
a scheduler can alert on it — mirroring forward_collection_gap_alert. Tests +
operations docs included. Full suite 947 green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Closes the GA-blocker "in-place upgrade on a populated DB is untested" (CI only
migrated a fresh empty DB forward). A TransactionTestCase creates a ForwardSource
under the pre-destructive schema (0024), migrates through the destructive
migrations (0025 device-analysis rebuild, 0028 execution-run removal) to head, and
asserts the source and its parameters survive. Restores the shared test DB to head
in tearDown. Full suite 948 green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The Forward API password was plaintext in the ForwardSource parameters JSONField
(masking display-only), so a DB dump held a usable credential. It is now encrypted
at rest with Fernet keyed off Django SECRET_KEY:

- utilities/crypto.py: encrypt_secret/decrypt_secret (enc:v1: prefix), idempotent
  encrypt, plaintext passthrough on decrypt, fail-open-to-raw + log on decrypt
  error (SECRET_KEY change).
- ForwardSource.save() encrypts parameters["password"]; the client decrypts at the
  single HTTP-auth consumer. No other reader changes (presence checks stay truthy;
  the password field never renders its value).
- Migration 0031 encrypts existing plaintext passwords (reversible).
- Backward compatible: pre-migration rows and fresh plaintext form input both
  authenticate via passthrough.

Consequence documented in SECURITY.md/operations.md: rotating SECRET_KEY requires
re-entering each source's password. Full suite 955 green; no migration drift.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
compute_scope_reconciliation resolves out-of-scope device names to explicit PKs at
compute time (_out_of_scope_pks) and prune_orphan_devices deletes those PKs
directly, removing the fragile delete-time re-match on the non-unique device name.
Scope membership stays name-keyed (a Forward-scoped name conservatively protects
every same-named NetBox device); full cross-site same-name disambiguation needs
Forward location->site mapping, noted inline as a separate change. Suite green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Exposes Forward sync/job health as Prometheus text-exposition metrics
(source/sync/ingestion counts, forward_jobs by status, forward_stuck_jobs, and the
most-recent-completed-job timestamp/age) so a Grafana/Datadog stack can graph and
alert on it — closing the "telemetry trapped in job.data/health page" gap.
Read-only, dependency-free, consumable by a node_exporter textfile collector or
scrape sidecar. Test + operations docs included.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- .coveragerc rewritten to a valid standalone config (the old [coverage:*]
  sections only work embedded in setup.cfg, so coverage silently ignored it).
- development/Dockerfile installs coverage; the CI plugin-test step now runs under
  coverage and enforces --fail-under=70 (measured baseline 76%).
- constraints.txt pins the tested runtime deps (cryptography/httpx/
  netboxlabs-netbox-branching/pyzipper); pip-audit now audits it (tested==shipped).
- Documented the min+latest NetBox matrix policy; v4.6.4 is currently both (newest
  published 4.6.x), so no unverified version was added.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the "unsupported / at your own risk / no warranty / not an official Forward
product" disclaimer with a Support section: officially maintained Forward Networks
integration, support targets the latest release, bug/security/upgrade channels
stated. Bump the pyproject Development Status classifier to 5 - Production/Stable.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bump 2.2.5 -> 2.3.0 (pyproject, __init__, README compat tables, CHANGELOG) + the
2.3.0 release plan/notes. Bundles the enterprise-hardening tranche: encrypted
credential at rest, Trusted Publishing + SBOM, Prometheus metrics + stuck-job
alert, populated-DB upgrade test, dead-code removal, reliability fixes, and
supported-product framing. Drop-in from 2.2.5 (stored credentials auto-encrypt;
rotating SECRET_KEY requires re-entry). Fixes a stale ==1.7.2 install example and a
forward_metrics 3-tuple JobStatusChoices.CHOICES unpack.

NOT released — prepared only; publish deferred to a later turn via the tag-triggered
Trusted-Publishing workflow.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…d supported table

The tranche-1 plan doc re-committed the customer-derived test name in its own
Touched-Surfaces list; reworded to name neither the customer nor a personal
path. SECURITY.md 'Supported versions' listed 2.2.x and omitted the shipping
release; now release-agnostic (latest = 2.3.x).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
CI ran only check_sensitive_content.py --all-history, which scans commit
MESSAGES, never file CONTENT — how a customer name shipped in a tracked doc
twice. Add a --git-files content-scan step (same FORWARD_SENSITIVE_PATTERNS
secret) so a name in a doc/test/comment fails CI. Blocking; empty secret
yields no findings, so it's safe before the secret is populated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@dependabot @github

dependabot Bot commented on behalf of github Jul 4, 2026

Copy link
Copy Markdown
Contributor Author

Labels

The following labels could not be found: ci, dependencies. Please create them before Dependabot can add them to a pull request.

Please fix the above issues or remove invalid values from dependabot.yml.

captainpacket and others added 3 commits July 4, 2026 21:23
The plan-doc harness gate permanently blocked every Dependabot PR (they can't
carry a plan doc). Skip the gate for the dependabot[bot] actor only; human
changes still require a plan. Also switch release.yml to workflow_dispatch until
PyPI Trusted Publishing is configured, so release tags stop emitting a false
failed-publish run/email (2.3.0 was published via twine).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Maintainer configured the PyPI Trusted Publisher + pypi environment, so restore
the tag trigger (push: tags v*) plus manual dispatch; future release tags now
auto-publish via OIDC.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bumps [actions/checkout](https://github.com/actions/checkout) from 6 to 7.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](actions/checkout@v6...v7)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
@captainpacket

Copy link
Copy Markdown
Collaborator

Holding this bump: it changes actions/upload-artifact/download-artifact used only in release.yml (the PyPI publish path), which CI does not exercise — so a green check here does not prove the release still works. upload-artifact and download-artifact must stay on format-compatible major versions (v4 upload ↔ v4 download). Verify v7 upload ↔ v8 download compatibility, or merge #28 and #29 together and validate on the next release tag, before merging.

dependabot Bot and others added 9 commits July 4, 2026 21:28
Bumps [pyzipper](https://github.com/danifus/pyzipper) from 0.3.6 to 0.4.0.
- [Changelog](https://github.com/danifus/pyzipper/blob/master/HISTORY.rst)
- [Commits](danifus/pyzipper@v0.3.6...v0.4.0)

---
updated-dependencies:
- dependency-name: pyzipper
  dependency-version: 0.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Updates the requirements on [pymdown-extensions](https://github.com/facelessuser/pymdown-extensions) to permit the latest version.
- [Release notes](https://github.com/facelessuser/pymdown-extensions/releases)
- [Commits](facelessuser/pymdown-extensions@10.15...11.0.1)

---
updated-dependencies:
- dependency-name: pymdown-extensions
  dependency-version: 11.0.1
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…rges)

The actor-only exemption skipped the gate on Dependabot PR runs but not on the
merge-to-main push (actor there is the merger), so each merged dep bump re-flagged
its pyproject/workflow change with no plan doc and redded main. Gate now runs only
on pull_request events for non-Dependabot actors; direct pushes stay covered by
local invoke harness-check.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
check_harness required literal actions/checkout@v6 + setup-python@v6 in ci.yml;
Dependabot's checkout v6->v7 bump broke that fragment check (failing local
harness-check and human PRs). Match the action prefix version-agnostically so
future action-version bumps don't red the gate.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ols)

The folded `if: >-` block got collapsed by yamlfmt to an 82-char line, tripping
yamllint. Use a single <=80 line with github.head_ref (empty on push, set on PRs)
so the gate still runs only on non-Dependabot PRs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Updates the requirements on [invoke](https://github.com/pyinvoke/invoke) to permit the latest version.
- [Commits](pyinvoke/invoke@2.2.0...3.0.3)

---
updated-dependencies:
- dependency-name: invoke
  dependency-version: 3.0.3
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
- apply_extras_taggeditem now coalesces on (slug, name): an existing NetBox tag
  with the same name but a different slug is reused, not re-created (fixes the
  'Tag with this Name already exists' ingestion error on 2.3.0).
- drift report flags itself stale when a sync ran after the cached preview it is
  built from, so operators re-run Preview Dependencies instead of reading old
  'everything to create' drift.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…34)

- Reword two regression comments to drop an internal name reintroduced in 2.3.1.
- release.yml SBOM: cyclonedx-py --outfile -> --output-file (renamed CLI flag
  failed the build job and skipped the tag-triggered publish) + continue-on-error
  so a supplementary SBOM never gates a publish.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 7.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](actions/upload-artifact@v4...v7)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot force-pushed the dependabot/github_actions/actions/upload-artifact-7 branch from f7e2188 to 7209e5b Compare July 6, 2026 05:57
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