feat(github-actions): add sync-assets composite action - #285
Merged
Conversation
mmanciop
marked this pull request as draft
September 10, 2026 17:54
Wraps `dash0 apply --since <ref>` and resolves whether --since is safe to pass from the triggering GitHub Actions event, so a workflow doesn't have to hand-write the github.event.before gating that pattern otherwise requires (git's all-zeros SHA sentinel on a branch's first push, before being unset on workflow_dispatch/schedule/pull_request, and correct quoting). The since input has three states: auto (derive from the event, the default), none (unconditionally disable deletion detection), or any other value (an explicit comparison ref, for triggers with no before). An explicit empty string or all-zeros SHA fails the job immediately instead of being folded into the same "nothing to do" path as auto finding no prior state -- unlike the event-derived case, an explicit override has no routine excuse for either value and it's almost always a broken expression. Before invoking dash0, the action verifies a resolved ref both resolves in the checkout and is an ancestor of HEAD, since the action always passes --force (no TTY for a confirmation prompt in CI) -- once --force is set, apply --since's own non-ancestor handling degrades to a stderr-only warning, so this preflight restores a real backstop against a force-pushed or rewritten branch. accept-non-ancestor-ref is the explicit opt-out. The action always runs a zero-API-call `apply --dry-run --agent-mode` preflight first, exposing structured deletions/modifications outputs and enforcing an optional max-deletions circuit breaker before any mutating call -- dry-run combined with since: none needs no credentials at all. Includes README, docs/github-actions.md and docs/github-actions-maintenance.md updates, sync-docs transformation entries, a changelog entry (tracking issue #277), and a test workflow covering ref resolution and its explicit- empty/all-zeros hard failures, the ancestry preflight and its opt-out, dry-run plan outputs, the max-deletions circuit breaker, and a real end-to-end create/delete cycle.
mmanciop
force-pushed
the
feat/sync-assets-action
branch
from
September 10, 2026 18:08
9cf7eb7 to
4d989cb
Compare
Squashing the branch history dropped three fixes made against CI feedback on PR #285; reapplying them on top of the new base commit: - arm64 job invoked the action with path: ci-scratch without ever creating that directory, so the real (non-wrapped) CLI failed with "no such file or directory". Add the same scratch-fixture step every other ci-scratch job already has. - End-to-end deletion check used `dashboards get`, but Dash0 soft-deletes assets (dash0.com/deleted-at), so get by id still returns a deleted dashboard. Switch to `dashboards list --all -o json`, matching how test/roundtrip/test_dashboard_roundtrip.sh already verifies deletion. - Four job names started lowercase because they led with a code identifier (since, accept-non-ancestor-ref, dry-run, max-deletions); capitalized them to match every other job name in the file.
mmanciop
marked this pull request as ready for review
September 10, 2026 18:16
- since: auto no longer derives a comparison ref on pull_request events, even though synchronize sets github.event.before -- with real credentials and dry-run: false, that before was resolvable and an ancestor, so a PR that temporarily removed an asset file would delete the live asset via the action's internal --force. auto now only derives from a push event; pull_request/workflow_dispatch/schedule always need an explicit since ref for deletion detection. - cli-version's minimum is 1.17.0, not 1.1.0: this action depends on apply --since and --dry-run --agent-mode JSON output, both introduced there. resolve-cli-version.sh gained an optional MIN_VERSION override (default unchanged at 1.1.0) so sync-assets can enforce its own floor without affecting setup/send-log-event. - Profile detection now reads `dash0 config show -o json` instead of grepping the human-readable output, which agent-mode auto-detection (e.g. GITHUB_COPILOT) can silently switch to JSON, causing this action to overwrite an existing same-named profile instead of updating it. - git merge-base --is-ancestor's exit code is now checked precisely: only exit 1 (genuinely not an ancestor) is treated as a possible force-push; any other nonzero exit is always a hard failure, since accept-non-ancestor-ref should never mask an unrelated git error. - The unresolvable-ref error message now also names a force-push/rebase orphaning history as a possible cause, since no checkout depth fetches commits unreachable from any branch or tag. - max-deletions now validates its value is a non-negative integer before use, with a clear ::error:: instead of an opaque `integer expression expected` failure under set -e. - Fixed lazy "deletion(s)"/"asset(s)" pluralization in the action and README per docs/code-style.md. - Dropped a test assertion on a composite step's outputs after that same step intentionally failed (unclear whether GitHub Actions guarantees those get published); the sibling failure tests already assert only on outcome. - README bullets trimmed to state observable behavior; the rationale moved to docs/github-actions-maintenance.md. - Shrunk the changelog subtext. - Added a regression test asserting since: auto omits --since when this workflow itself runs on a pull_request trigger.
Removed redundant explanation about the 'since' input states and preflight checks.
sync-assets and send-log-event each had an almost-identical inline "Create or update Dash0 profile" step. Extract it to .github/actions/lib/ensure-profile.sh, following the existing resolve-cli-version.sh/download-cli.sh pattern. This also fixes send-log-event's copy of the agent-mode profile detection bug (grepping dash0 config show's human-readable output, which agent mode -- auto-detected from env vars like GITHUB_COPILOT -- switches to JSON) that was already fixed in sync-assets but not propagated to its sibling. REQUIRE_PROFILE parameterizes the one real behavioral difference: send-log-event always needs credentials (hard error), sync-assets has a credential-free dry-run path (soft warning).
ensure-profile.sh's dash0 config show -o json unconditionally broke send-log-event's own supported floor (CLI 1.1.0): -o json for config show landed in v1.8.0 alongside agent mode itself, so an older CLI rejects the unknown -o flag outright, and the script (set -e) died silently with no output. sync-assets was unaffected since its own floor is already 1.17.0. Falls back to the old human-readable-output parsing when -o json itself fails. Safe by construction: a CLI old enough to lack -o json also lacks agent-mode auto-detection, so the JSON-output trap that `-o json` exists to dodge cannot occur on that fallback path.
nicolastakashi
approved these changes
Sep 14, 2026
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
Wraps
dash0 apply --since <ref>and resolves whether --since is safe to pass from the triggering GitHub Actions event, so a workflow doesn't have to hand-write thegithub.event.beforegating that pattern otherwise requires (git's all-zeros SHA sentinel on a branch's first push, before being unset onworkflow_dispatch/schedule/pull_request, and correct quoting).