Skip to main content

create-pr

Create a pull request for the current branch with proper labels and description. Any agent opening a PR in this repo (via `gh pr create` or otherwise), whether invoked directly as /create-pr or as part of a larger task, MUST follow this skill's process rather than improvising.

Source facts

Repository
DataDog/datadog-agent
Last source activity
October 25, 2026 at 11:30
Detected SKILL.md language
English
Stars
3,771
Forks
1,518

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
2 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
create-pr
description
Create a pull request for the current branch with proper labels and description. Any agent opening a PR in this repo (via `gh pr create` or otherwise), whether invoked directly as /create-pr or as part of a larger task, MUST follow this skill's process rather than improvising.
allowed-tools
Bash, Read, Glob
argument-hint
[--real] [additional labels...]
model
sonnet
Create a pull request for the current branch following the Datadog Agent contributing guidelines. **This is the canonical process for opening PRs in this repo.** `disable-model-invocation: true` only means the harness won't auto-invoke this skill as a tool call — it does not mean the process below is optional. Whenever you (or another agent/skill working in this repo) are about to run `gh pr create` for any reason — not just when the user explicitly types `/create-pr` — read and follow the steps below instead of assembling a title/body/labels ad hoc. **Ownership:** maintained by `@DataDog/agent-devx`. **Prerequisites:** the `gh` CLI must be installed and authenticated (`gh auth status`) with access to `DataDog/datadog-agent`, and `origin` must point at that repo (or a fork with push access) so `git push` and `gh pr create` succeed. ## Instructions 1. **Check the current branch**. - If the current branch is `main` (or the default branch): - Check for uncommitted or staged changes (`git status`). If there are changes, create a new feature branch from the default branch (`git checkout -b <branch-name>`), stage the changes, commit, and push. - If there are no changes at all, stop and inform the user there is nothing to open a PR for. - If the current branch is a feature branch that already has an open PR (`gh pr list --head <branch> --state open`), check whether the uncommitted/staged changes and unpushed commits are actually related to that PR's existing work. If they are a distinct, unrelated change, don't pile them onto the existing PR/branch — create a new feature branch from the default branch (`git checkout main && git pull && git checkout -b <branch-name>`), then cherry-pick/move the relevant changes onto it, commit, and push, so the unrelated change gets its own PR. If genuinely unsure whether the changes are related, ask the user. 2. **Get the commits** on this branch compared to `main` using `git log main..HEAD` 3. **Get the diff** using `git diff main..HEAD` to understand all changes 4. **Read the PR template** from `.github/PULL_REQUEST_TEMPLATE.md` 5. **Local code review**: Run the review script. It runs `dda review`, which builds the same prompt as the PR `Code review` workflow (`.github/workflows/code-review.yml`) from the `codereview_guideline.md` files relevant to the diff, against the repository default branch: ```bash .agents/skills/create-pr/scripts/review.sh ``` The script uses the first reviewer that is available, and tries the next one if a review fails: 1. `codex` on the host, the same provider as CI, so findings should match what CI will post 2. `claude` on the host 3. `claude` in a `dda env dev` developer environment, which needs docker and authenticates through `ddtool`. The environment is kept for later runs. An LLM review takes several minutes. Don't give it a short timeout and don't let it get killed mid-run: launch it asynchronously (e.g. `run_in_background: true` in Claude Code) and poll until it finishes, or give it a timeout of at least 10 minutes. Allow 20 minutes when it starts a developer environment, since the first start pulls a large image. If it still hasn't finished by then, tell the user and continue without it rather than stalling PR creation indefinitely. Outcomes, by exit code: - **0, review completed**: show the findings to the user, and say which reviewer ran when it wasn't `codex`, since CI uses `codex`. Findings don't block PR creation; fix them first only if the user asks. - **1, every attempted review failed**: tell the user, with the errors, and continue. - **2, no reviewer available**: never skip this silently. Show the user the alert and the reasons the script printed, then continue. 6. **PR title**: Use [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) format, prefixed with the general area of change. Examples: - `fix(e2e): Fix flaky diagnose test` - `feat(logs): Add new log pipeline` - `refactor(config): Simplify endpoint resolution` 7. **Draft a concise PR description** from the commits and diff. See "PR Description Guidelines" below — keep the draft short and plain, like a human wrote it in two minutes, not AI-generated prose. Present the draft body (What does this PR do? / Motivation, at minimum) directly in your reply so the user can review it — but don't block on confirmation: since PRs open as drafts by default (step 12), the user can review and edit the description directly from the GitHub UI, which is usually faster than relaying corrections through the agent. If the user has given corrections or missing context during the session (e.g. the real motivation, an issue link, a tradeoff worth mentioning), fold it in. The one exception is a non-draft PR (`--real`): a PR marked ready for review implies its description is final, so get explicit confirmation on the draft before opening it. 8. **Check for a needed backport** (see "Backport Detection" below) and note the matching `backport/<branch>` label(s) if applicable. 9. **Labels**: Choose appropriate labels (plus any additional labels passed as $ARGUMENTS): - If the PR only changes tests, docs, CI config, or developer tooling (no Agent binary code changes), use `changelog/no-changelog` and `qa/no-code-change` - If the PR changes Agent binary code and QA was done, use `qa/done` - A reno release note is only expected for **customer-facing changes** — not for every PR that touches Agent binary code. See "Release Notes" below for what qualifies; if the change isn't customer-facing, use `changelog/no-changelog` - Add any `backport/<branch-name>` labels identified in step 8, or if the user explicitly asks for a specific backport 10. **PR body**: Fill in the PR template sections: - **What does this PR do?**: A clear description of what is changed, based on the user's concise description from step 7. Must be readable independently, tying back to the changed code. - **Motivation**: A reason why the change is made. Point to an issue if applicable. Include drawbacks or tradeoffs if any. - **Describe how you validated your changes**: How you validated the change (tests added/run, benchmarks, manual testing). Only needed when testing included work not covered by test suites. - **Additional Notes**: Any extra context, links to predecessor PRs if part of a chain, notes that make code understanding easier. **Only include this section if there is genuinely useful context to add** — omit it entirely rather than filling it with filler. 11. **Push the branch** to origin if needed 12. **Open the PR**: Now that the title, body, and labels are finalized, open the PR. By default, open as **Draft** using `gh pr create --draft`. If `$ARGUMENTS` contains `--real`, open as a regular (non-draft) PR instead (omit the `--draft` flag). Remove `--real` from `$ARGUMENTS` before processing remaining arguments as labels. 13. Once the PR is pushed, ask the user if they want to follow CI status for this PR. If yes, invoke the `/follow-pr` skill. ## PR Description Guidelines (from CONTRIBUTING.md) The PR description should incorporate everything reviewers and future maintainers need: - A description of what is changed - A reason why the change is made (pointing to an issue is a good reason) - When testing had to include work not covered by test suites, a description of how you validated your change - Any relevant benchmarks - Additional notes that make code understanding easier - If part of a chain of PRs, point to the predecessors - If there are drawbacks or tradeoffs, raise them **Avoid AI slop.** Reviewers can tell when a PR description was auto-generated from a diff — padded, generic, restating the code instead of explaining intent. To avoid this: - Draft the description yourself (step 7) and show it to the user, but don't gate the PR on their sign-off — for draft PRs they can edit the description in the GitHub UI faster than explaining what to fix. Don't outsource the writing to the user either. - Keep it short. A few sentences beat a bulleted essay. Don't restate every changed file — the diff already shows that. - Don't pad sections with filler when there's nothing to say (e.g. an empty-but-present "Additional Notes" section, or a "Describe how you validated" filled with "N/A" — omit instead). - Write plainly, the way the user would describe it in Slack to a teammate, not like a press release ("This PR introduces a robust, comprehensive solution to..."). ## Release Notes Only **customer-facing changes** need a reno release note — something a Datadog customer could notice in the shipped agent. Most PRs, including most that touch Agent binary code, don't need one. When unsure whether a change is customer-facing, mention it to the user rather than defaulting either way. **Needs a release note:** - New customer-facing functionality (e.g. "Add support for collecting X on Y") - Bug fixes customers can hit (e.g. "Fix panic in the log agent when a tailed file is deleted") - Visible behavior changes: new/renamed/removed metrics or tags, changed default values - Deprecations, breaking changes requiring user action, security fixes **No release note** (use `changelog/no-changelog`): - Internal refactors, dead-code removal, internal APIs and telemetry - Test-only, docs-only, CI/CD, invoke tasks, bazel/build, and other developer tooling - Dependency bumps and code cleanups with no customer-visible impact - Comments, formatting, and other cosmetic changes ## Backport Detection Before finalizing labels, determine whether this change likely needs to be backported to a release branch: 1. **List "living" release branch labels**: run `gh label list --search backport/7 --limit 5`. We can limit to 5 as there should not be more than 2 active releases. Equivalently: `gh api repos/{owner}/{repo}/labels --paginate --jq '.[] | select(.name | startswith("backport/7")) | .name + " | " + (.description // "")'`. Only labels whose description mentions automatic backport-PR creation (e.g. "Automatically create a backport PR to ... once the PR is merged") correspond to *active* release branches — the repo keeps many old `<version>.x` branches around that are no longer maintained, so branch existence alone (`git ls-remote --heads origin`) is not a reliable signal. 2. **Compare against the base branch's target milestone**: read `release.json`'s `base_branch` / `current_milestone` to see what's currently in development on `main`. A change merged to `main` is typically only backported if the same fix is needed in a still-supported release (e.g. a bug also present in the currently-shipping minor version). 3. **Decide relevance**: this is a judgment call, not automatic — a new feature usually does not need a backport; a bug fix, security fix, or CI/build resilience fix often does, if the affected release branch(es) still exist and are active. If genuinely unsure, ask the user. 4. **If a backport is warranted**, propose the specific `backport/<version>.x` label(s) to the user for confirmation before adding them — don't silently add backport labels. ## Example ```bash gh pr create --draft \ --title "fix(e2e): Fix flaky diagnose test by adding missing fakeintake redirect" \ --label "changelog/no-changelog" \ --label "qa/no-code-change" \ --body "$(cat <<'EOF' ### What does this PR do? The diagnose E2E test flaked because it hit fakeintake directly instead of through the redirect the agent config sets up. Route it through the same path the agent uses. ### Motivation Flaked ~1 in 5 runs on main, blocking merges for unrelated PRs. ### Describe how you validated your changes Ran the test 20x locally with the fix; no failures (previously failed ~4/20). EOF )" ``` Note there is no "Additional Notes" section here — it was omitted because there was nothing beyond the two sections above worth adding, per the "no filler" guidance. ## Usage - `/create-pr` — creates a draft PR (default) - `/create-pr --real` — creates a non-draft PR - `/create-pr --real team/my-team` — non-draft PR with an extra label ## Output If you are not following the PR status (step 13): Return the PR URL when done. Otherwise, defer to `/follow-pr`.
View on GitHub