-
Notifications
You must be signed in to change notification settings - Fork 25
Permalink
Choose a base ref
{{ refName }}
default
Choose a head ref
{{ refName }}
default
Comparing changes
Choose two branches to see what’s changed or to start a new pull request.
If you need to, you can also or
learn more about diff comparisons.
Open a pull request
Create a new pull request by comparing changes across two branches. If you need to, you can also .
Learn more about diff comparisons here.
base repository: DataDog/datadog-sync-cli
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 4.5.0
Could not load branches
Nothing to show
Loading
Could not load tags
Nothing to show
{{ refName }}
default
Loading
...
head repository: DataDog/datadog-sync-cli
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 4.6.0
Could not load branches
Nothing to show
Loading
Could not load tags
Nothing to show
{{ refName }}
default
Loading
- 3 commits
- 5 files changed
- 3 contributors
Commits on May 22, 2026
-
fix(roles): reconcile source state when destination silently drops pe…
…rmissions (#572) * fix(roles): reconcile source state when destination silently drops permissions The Datadog roles API silently drops some permission IDs on create/update without returning a 400 — e.g. permissions that are gated by feature flags, imply each other, or are not grantable to the role being modified. This broke test-integrations on main from 2026-05-21 onward: after `sync`, the destination role had fewer permissions than the source role's permission set, and the follow-up `diffs` run flagged the divergence as `iterable_item_added`, failing the `assert "diff:" not in caplog.text` check across test_sync, test_migrate, and test_cleanup. After a successful create/update PATCH, the API response is authoritative — it reflects what was actually persisted. This change compares the requested vs. persisted permission set and, when the destination dropped some, reverse-maps the dropped destination UUIDs back to permission names and trims the in-memory source state to match. Subsequent diff comparisons within the same run, and subsequent `diffs` invocations after `sync` dumps state to disk, see a converged permission set on both sides. Source-on-disk is re-imported from the source org on the next `import` run, restoring the canonical view. The on-disk source state files (written by `import`) intentionally reflect source org state. We only adjust the in-memory representation after a sync action so the diff in the same `sync`-then-`diffs` flow converges; the next `import` will rehydrate source state from the source org. Added unit tests covering: trimming on drop, no-op when destination persists everything, no-op when no permissions requested, graceful handling of missing source state. All 608 unit tests pass. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * fix(roles): also reconcile built-in role permissions in pre-action hook The previous reconciliation in `_reconcile_persisted_permissions` runs after the destination API call returns — but built-in roles (Datadog Admin/Standard/Read Only) never reach the API call: `create_resource` returns the pre-fetched destination role without POST, and `update_resource` raises SkipResource before PATCH. So for the exact roles the test_cli integration job was flagging (3020f50c "Datadog Admin Role", 302b4f34 "Datadog Standard Role", 3032ffb8 "Datadog Read Only Role"), the persisted- permissions reconciler was never invoked, and the `iterable_item_added` diff for `relationships.permissions.data` reappeared on the post-sync `diffs` run. The destination org's built-in roles legitimately carry a different permission set than the source org (feature flags, sub-org policy, product entitlements). Since we can't mutate built-ins via the API, the only way to make sync idempotent is to trim the source side to match the destination side at diff-comparison time. `_reconcile_builtin_role_permissions` runs from `pre_resource_action_hook`, which fires for both sync and diffs flows. It intersects the working copy's permissions (already remapped to destination UUIDs by `remap_permissions`) with the destination role's actual permissions from `_existing_resources_map[role_name]`, and applies the trimmed set to both the working copy and `state.source` (for `dump_state` to persist after sync). Non-built-in roles are untouched. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> --------- Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
Configuration menu - View commit details
-
Copy full SHA for 1b45cea - Browse repository at this point
Copy the full SHA 1b45ceaView commit details -
Make TaggingConfig.add_default_tags idempotent (#571)
When a resource already carries `managed_by:datadog-sync` from a prior sync (e.g. multi-hop chains: source -> R1 -> R2), the previous code unconditionally extended the tags list, producing duplicates that the destination API rejects with `400 Bad Request - "All items in parameter 'tags' must be unique"`. Repro'd today: SLO `e74398cbd95a5ca09827b30950d8f0c4` was rejected by R2 on the second hop. Affects 7 resource types using TaggingConfig: monitors, service_level_objectives, synthetics_tests, synthetics_global_variables, synthetics_private_locations, synthetics_mobile_applications, synthetics_test_suites. Also defensively copies `self.default_tags` when first-setting the tags field so callers can't accidentally mutate the class-level list.
Configuration menu - View commit details
-
Copy full SHA for ddef61f - Browse repository at this point
Copy the full SHA ddef61fView commit details -
Co-authored-by: dd-octo-sts[bot] <200755185+dd-octo-sts[bot]@users.noreply.github.com>
Configuration menu - View commit details
-
Copy full SHA for 272667f - Browse repository at this point
Copy the full SHA 272667fView commit details
Loading
This comparison is taking too long to generate.
Unfortunately it looks like we can’t render this comparison for you right now. It might be too big, or there might be something weird with your repository.
You can try running this command locally to see the comparison on your machine:
git diff 4.5.0...4.6.0