Skip to content

Latest commit

 

History

History

utils

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

Utility Scripts

This directory contains utility scripts for managing the java-profiler project.


Release

release.sh

Triggers the Validated Release workflow using GitHub CLI to create a new release.

Prerequisites:

  • GitHub CLI installed and authenticated
  • jq installed
  • Git repository is up to date
  • The authenticated user has write, maintain, or admin repository access
  • You are on the correct branch for the release type

Usage:

./utils/release.sh <release_type> [options]

Arguments:

  • release_type: Type of release (major, minor, or patch)

Options:

  • --no-dry-run: Actually perform the release (default is dry-run)
  • --skip-tests: Skip pre-release tests (emergency releases only)
  • --branch <name>: Specify branch to release from (default: current branch)
  • --commit <sha>: Specify commit SHA to release (default: interactive selection)
  • --help: Show help message

Branch rules:

  • Major/Minor releases: must be run from main
  • Patch releases: must be run from a release/X.Y._ branch

Release flow:

  1. Validates inputs and branch rules
  2. Fetches and verifies the selected branch is up to date with origin (a checked-out local branch that's behind or ahead of origin fails fast with pull instructions)
  3. For patch releases, asks whether to pick PRs from main to backport onto the release branch first; if you accept, you select which PRs, a combined backport PR is opened, and the script exits so you can merge it and re-run
  4. Interactive commit selection (or use --commit)
  5. Triggers GitHub Actions "Validated Release" workflow
  6. Workflow runs pre-release tests, then creates the annotated tag on the selected commit (and a release branch for minor/major releases)
  7. Tag push triggers GitLab, which publishes the Maven artifacts, and the GitHub release workflows attach the release assets

No file modifications or version-bump PRs are needed — the version is computed from git tags at build time. The next build from main (or the release branch) automatically sees the new tag and computes the next snapshot version.

Interactive pickers (branch and commit selection) support ↑/↓/Enter, and can be cancelled at any time with q or Ctrl-C.

A dry run never creates a tag, pushes a branch, or triggers GitLab.

If workflow monitoring loses its API connection, the script checks the run's status and reconnects to the same run, making up to three monitoring attempts per monitoring window. All attempts share a one-hour deadline. When the deadline is reached, the script allows up to ten seconds for a final status query, including when it must retry a query interrupted by the shared deadline. If the result remains unconfirmed, an interactive session asks whether to watch the same run for another hour. Answering y or yes renews the deadline and monitoring attempts. Answering n, pressing Enter, or reaching EOF stops monitoring with WORKFLOW STATUS UNKNOWN and a nonzero exit. Unattended sessions stop without prompting. The remote workflow keeps running when local monitoring stops. RELEASE_MONITOR_TIMEOUT_SECONDS overrides the default 3600-second deadline. Check the existing run before starting another release. Recognized completed outcomes retain GitHub's exact conclusion in the output. Only a confirmed success exits zero; other recognized conclusions exit nonzero. Only failure and startup_failure are labelled as workflow failures.

Testing release automation

.github/scripts/tests/test_release_automation.sh is a single hermetic shell test. It validates release tag/branch creation, version computation, trivial-PR authorization, and recovery from workflow monitoring errors using temporary local Git repositories and a GitHub CLI fixture. It does not load credentials or contact GitHub, so it cannot publish, tag, push, or merge anything remotely. The terminal interaction tests require Python 3.

.github/scripts/tests/test_release_automation.sh

Backport

backport-pr.sh

Cherry-picks a merged PR onto a release branch, pushes the backport branch, and opens a PR.

Prerequisites:

  • GitHub CLI installed and authenticated
  • jq installed
  • Clean working tree

Usage:

./utils/backport-pr.sh [--dry-run] [<release-name>] <pr-number-or-url>

Arguments:

  • <release-name>: Target release branch suffix, e.g. 1.9._ (maps to release/1.9._). If omitted, an interactive picker is shown.
  • <pr-number-or-url>: PR number (420) or full GitHub URL.
  • --dry-run: Preview without making changes.

Examples:

./utils/backport-pr.sh 1.9._ 420
./utils/backport-pr.sh 420          # interactive branch selection
./utils/backport-pr.sh --dry-run 1.9._ 420

prepare-patch.sh

Finds PRs merged to main since a release branch diverged, lets you multi-select which ones to backport, cherry-picks them onto a single new branch off the release branch, runs ./gradlew buildDebug to catch a combination that doesn't build before pushing, and opens one combined PR. Also invoked interactively from release.sh when preparing a patch release.

Prerequisites:

  • GitHub CLI installed and authenticated
  • jq installed
  • Clean working tree

Usage:

./utils/prepare-patch.sh [--branch release/X.Y._] [--no-dry-run]

Options:

  • --branch <name>: Release branch to prepare. If omitted, an interactive picker is shown.
  • --no-dry-run: Actually cherry-pick, push, and open the PR (default is dry-run).

Examples:

./utils/prepare-patch.sh --branch release/1.9._            # dry-run, preview only
./utils/prepare-patch.sh                                   # interactive branch selection, dry-run
./utils/prepare-patch.sh --no-dry-run --branch release/1.9._

Test candidate discovery with local Git repositories and a GitHub CLI fixture:

bash utils/tests/test_prepare_patch.sh

Testing

run-containers-tests.sh

Runs tests in containers across various OS/libc/JDK combinations, mirroring the CI matrix locally. Defaults to Podman; on macOS use Docker via colima (--container=docker) — podman's credential-helper lookup for the Datadog registries (ddtool) fails outside the CI network and aborts container commands.

Usage:

./utils/run-containers-tests.sh [options]
  --libc=glibc|musl|all[,..]      (default: glibc)
  --jdk=8|11|17|21|25|8-j9|...|regular|j9|graal|all[,..]
                                    (default: 21)
  --arch=x64|aarch64|all[,..]     (default: auto-detect)
  --config=debug|release|asan|tsan|all[,..] (default: debug)
  --container=podman|docker       (default: podman)
  --tests="TestPattern"           (optional)
  --gtest                         (enable C++ gtests)
  --gtest-task=Task               (run one C++ gtest task)
  --shell                         (drop to shell instead of running tests)
  --mount                         (mount local repo instead of cloning)
  --rebuild                       (force rebuild of container images)
  --matrix                        (preview a full matrix)
  --run                           (execute an inferred matrix without prompting)
  --fail-fast                     (stop matrix execution on first failure)

Examples:

# Run a single C++ gtest binary in ASan mode
./utils/run-containers-tests.sh --config=asan --gtest-task=elfparser_ut

# Use Docker via colima (recommended on macOS)
./utils/run-containers-tests.sh --container=docker --libc=glibc --jdk=21

# Preview selected JDKs across every supported libc/architecture pair
./utils/run-containers-tests.sh --libc=all --jdk=8,17,21 --arch=all

# Run all supported musl cells without an interactive prompt
./utils/run-containers-tests.sh --matrix --libc=musl --run

# Run all OpenJ9 cells
./utils/run-containers-tests.sh --matrix --jdk=j9 --run

Single-value commands run one container test configuration immediately. When any dimension expands to multiple cells, the script prints a compact status table first; interactive terminals ask for confirmation, while non-interactive runs require --run to execute. Matrix execution prints the status table again after all cells finish and writes summaries to build/reports/container-matrix/summary.md and build/reports/container-matrix/summary.json. Matrix gtest runs require a short --gtest-task name so the task follows each cell's configuration. Cells not run because of --fail-fast are reported as cancelled separately from unsupported cells that are skipped.

check-signal-reachability.py

Static async-signal-safety check. Builds a call graph from the relocations of the debug object files (objdump -dr) and reports every function reachable from a signal handler or malloc hook that calls an unsafe symbol (heap allocation, locks, stdio, dynamic-loader calls, dynamic TLS, logging). The entry points, unsafe symbols and known findings are data lists at the top of the script. ELF objects only (Linux x64/aarch64); needs GNU objdump and c++filt.

Usage:

./utils/check-signal-reachability.py --obj-dir ddprof-lib/build/obj/main/debug [--allowlist <file>]
./utils/check-signal-reachability.py --self-test   # planted violations in utils/tests/signal-reachability-fixture.cpp
./gradlew :ddprof-lib:checkSignalReachability      # opt-in; SKIPPED when the debug objects are not ELF

Exit codes: 0 no findings outside the allowlist (or self-test passed), 1 new findings (one <object>:<caller> -> <unsafe symbol> (via <path>) line each), 2 usage/environment error. --allowlist replaces the built-in known findings; one entry per line: <caller>[|<caller>...] -> <unsafe symbol> # <JIRA-KEY>.

Source quality checks

Standalone, stdlib-only checks over the git-tracked files. Each prints one <path>[:<line>]: <problem> line per violation and exits 0 clean, 1 violations, 2 environment error; --root selects the checkout (default: the one containing the script).

Script Checks
check-jvm-boundary-includes.py Shared code in ddprof-lib/src/main/cpp does not #include "hotspot/", "j9/" or "zing/" headers (quoted or angle-bracket form), except the boundary files and the known exceptions (mirrors doc/architecture/JvmSupportLayer.md#known-boundary-exceptions).
check-doc-index.py Every doc/**/*.md is linked from doc/README.md and has a PascalCase file name.
check-sigsetjmp-shape.py Every sigsetjmp() has a JmpCtxScope in effect, savemask 1, and a landing pad that starts with SIGNAL_HANDLER_UNWIND_AFTER_LONGJMP(); then <scope>.restore(); (the guards.h pattern). The glibc cancellation buffer in libraryPatcher_linux.cpp is the one exception.
check-tracked-artifacts.py No tracked path under docs/sphinx/ or .sphinx/, and no *.scratch* path.

Usage:

./utils/check-doc-index.py                 # any one check
./gradlew :ddprof-lib:qualityChecks        # signal-reachability check (+ --self-test on Linux) plus all four; run by CI (ci.yml source-invariant-checks job)

patch-dd-java-agent.sh

Patches a dd-java-agent.jar with a locally-built ddprof library for quick local testing without a full dd-trace-java rebuild.

Usage:

DD_AGENT_JAR=path/to/dd-java-agent.jar DDPROF_JAR=path/to/ddprof.jar \
  ./utils/patch-dd-java-agent.sh

Upstream Tracking

See README_UPSTREAM_TRACKER.md for full documentation.

check_upstream_changes.sh

Wrapper to compare local files against a given upstream async-profiler commit and produce a change report.

track_upstream_changes.sh

Core change detection and report generation logic.

generate_tracked_files.sh

Identifies which local files should be tracked against upstream (based on async-profiler copyright headers).

check_contribution_candidates.sh

Identifies divergences from upstream async-profiler that could be contributed back.

find_contribution_candidates.sh

Core diff analysis and report generation for contribution candidate detection.


CI / Ops

update-sonatype-credentials.sh

Updates the Sonatype (Maven Central) OSSRH credentials stored in AWS SSM, used by the CI publish pipeline.

Prerequisites:

  • AWS CLI authenticated with ssm:PutParameter permission

Usage:

./utils/update-sonatype-credentials.sh <username> <token>