Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
221 changes: 221 additions & 0 deletions .github/workflows/release-dispatch.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
name: Release - Open a release proposal PR
on:
workflow_dispatch:
inputs:
crate:
description: Crate to release
required: true
type: choice
options:
- libdd-common
- libdd-crashtracker
- libdd-data-pipeline
- libdd-ddsketch
- libdd-dogstatsd-client
- libdd-library-config
- libdd-log
- libdd-profiling
- libdd-profiling-protobuf
- libdd-telemetry
- libdd-tinybytes
- libdd-trace-normalization
- libdd-trace-obfuscation
- libdd-trace-protobuf
- libdd-trace-stats
- libdd-trace-utils

env:
RELEASE_BRANCH: release

jobs:
make-release-pr:
permissions:
id-token: write # Enable OIDC
pull-requests: write
contents: write
needs: update-release-branch
runs-on: ubuntu-latest
# TODO: uncomment this when we have a way to test this workflow
# if: ${{ github.repository_owner == 'datadog' }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # 4.2.2
with:
fetch-depth: 0 # Need full history for git tags
- uses: chainguard-dev/actions/setup-gitsign@0cda751b114eb55c388e88f7479292668165602a # v1.0.2
- uses: Swatinem/rust-cache@f13886b937689c021905a6b90929199931d60db1 # v2.8.1
with:
cache-targets: true
- uses: dtolnay/rust-toolchain@nightly
- uses: dtolnay/rust-toolchain@stable
- uses: taiki-e/cache-cargo-install-action@7447f04c51f2ba27ca35e7f1e28fab848c5b3ba7 # 2.3.1
with:
tool: cargo-public-api # @0.50.2
- uses: taiki-e/cache-cargo-install-action@7447f04c51f2ba27ca35e7f1e28fab848c5b3ba7 # 2.3.1
with:
tool: cargo-release
- uses: taiki-e/cache-cargo-install-action@7447f04c51f2ba27ca35e7f1e28fab848c5b3ba7 # 2.3.1
with:
tool: git-cliff
- uses: taiki-e/cache-cargo-install-action@7447f04c51f2ba27ca35e7f1e28fab848c5b3ba7 # 2.3.1
with:
tool: cargo-semver-checks

- name: Get publication order for crate and dependencies
run: |
echo "Getting publication order for ${{ inputs.crate }}..."

# Get the publication order as JSON and save to file
./scripts/publication-order.sh --format=json "${{ inputs.crate }}" > /tmp/crates.json
echo "Publication order:"
cat /tmp/crates.json

- name: Get commits since last release for each crate
run: |
# Get commits since release for each crate and save to file
./scripts/commits-since-release.sh "$(cat /tmp/crates.json)" > /tmp/commits-by-crate.json

# Display summary
./scripts/commits-since-release.sh --format=summary "$(cat /tmp/crates.json)"

- name: Create a branch for the release proposal
id: proposal-branch
run: |
git checkout "${{ env.RELEASE_BRANCH }}"
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
BRANCH_NAME="release-proposal/${{ inputs.crate }}/$TIMESTAMP"
git checkout -b "$BRANCH_NAME"
git push origin "$BRANCH_NAME"
echo "Branch created: $BRANCH_NAME from $RELEASE_BRANCH branch"
echo "branch_name=$BRANCH_NAME" >> "$GITHUB_OUTPUT"

- name: Release version bumps
id: release-version-bumps
env:
ORIGINAL_HEAD: ${{ github.sha }}
run: |
echo "Release version bumps..."

# Initialize results array
echo "[]" > /tmp/api-changes.json

# iterate over the commits and execute cargo release for each crate
jq -c '.[]' /tmp/commits-by-crate.json | while read -r crate; do
NAME=$(echo "$crate" | jq -r '.name')
TAG=$(echo "$crate" | jq -r '.tag')
CRATE_PATH=$(echo "$crate" | jq -r '.path')
TAG_EXISTS=$(echo "$crate" | jq -r '.tag_exists')
COMMITS=$(echo "$crate" | jq -r '.commits')

if [ "$TAG_EXISTS" = "true" ]; then
RANGE="$TAG..$ORIGINAL_HEAD"
echo "Using $RANGE as range"

# TODO: Should we skip the release if the tag is not in the branch?
echo "Is the tag $TAG in the branch:"
git branch --contains "$TAG"

# TODO: Should we skip the release if the public API is not changed? (removed: 0, changed: 0, added: 0)

echo "Executing semver-level.sh for $NAME since $RANGE..."
SEMVER_LEVEL=$(./scripts/semver-level.sh "$NAME" "$TAG" 2>&1)
echo "Semver level: $SEMVER_LEVEL"

LEVEL=$(echo "$SEMVER_LEVEL" | jq -r '.level')

echo "Executing cargo release for $NAME since $TAG with level $LEVEL..."
cargo release version -p "$NAME" --prev-tag-name "$TAG" -x $LEVEL --no-confirm
else
RANGE="$ORIGINAL_HEAD"
echo "No previous release tag for $NAME, using $ORIGINAL_HEAD as range"

# Use the version from the crate metadata
LEVEL=$(echo "$crate" | jq -r '.version')

echo "Executing cargo release for $NAME with level $LEVEL..."
cargo release version -p "$NAME" -x $LEVEL --no-confirm

# if CHANGELOG.md does not exist, create it
if [ ! -f "$CRATE_PATH/CHANGELOG.md" ]; then
echo "Creating CHANGELOG.md for $NAME..."
touch "$CRATE_PATH/CHANGELOG.md"
fi
fi

# Update the CHANGELOG.md
NEXT_VERSION=$(cargo metadata --format-version=1 --no-deps | jq -r --arg name "$NAME" '.packages[] | select(.name == $name) | .version')
NEXT_TAG="$NAME-v$NEXT_VERSION"

# Check what commits git sees in the range
echo "Commits in the range $RANGE:"
git log --oneline "$RANGE" -- "$CRATE_PATH/"

echo "Executing git cliff for $NAME since $RANGE, next tag: $NEXT_TAG..."

# It seems that git cliff does not like to use tags that are not on the branch
git cliff --tag "$NEXT_TAG" --include-path "$CRATE_PATH/**/*" --prepend "$CRATE_PATH/CHANGELOG.md" --tag-pattern "$NAME-v.*" -u -v "$RANGE"
git add "$CRATE_PATH/CHANGELOG.md"

# Commit the changes
cargo release commit --no-confirm -x --sign-commit -vv

# Add to results array
jq --arg name "$NAME" --arg level "$LEVEL" --arg tag "$NEXT_TAG" --arg version "$NEXT_VERSION" '. += [{"name": $name, "level": $level, "tag": $tag, "version": $version}]' \
/tmp/api-changes.json > /tmp/api-changes.tmp && mv /tmp/api-changes.tmp /tmp/api-changes.json
done

# Output the results
echo "API changes summary:"
cat /tmp/api-changes.json | jq .

- name: Create a PR
env:
GH_TOKEN: ${{ github.token }}
run: |
BRANCH_NAME="${{ steps.proposal-branch.outputs.branch_name }}"

# Check if there are commits to push
if git diff --quiet origin/main; then
echo "No changes to push"
exit 0
fi

# Generate the PR body by merging commits and API changes
PR_BODY=$(jq -r --slurpfile api /tmp/api-changes.json '
.[] |
. as $crate |
($api[0] | map(select(.name == $crate.name)) | first // {level: "unknown"}) as $api_info |
"## \($crate.name)\n\n" +
"**Next version:** `\($api_info.version)`\n\n" +
"**Semver bump:** `\($api_info.level)`\n\n" +
"**Tag:** `\($api_info.tag)`\n\n" +
($crate.commits | map("- \(.subject)") | join("\n"))
' /tmp/commits-by-crate.json)

PR_BODY="# Release proposal for ${{ inputs.crate }} and its dependencies

This PR contains version bumps based on public API changes and commits since last release.

${PR_BODY}"

echo "PR_BODY: $PR_BODY"

git push origin "$BRANCH_NAME"
gh pr create \
--title "chore(release): proposal for ${{ inputs.crate }}" \
--body "$PR_BODY" \
--base "${{ env.RELEASE_BRANCH }}"

update-release-branch:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # 4.2.2
with:
fetch-depth: 0
fetch-tags: true
- name: Merge the main branch into the release branch
run: |
git fetch origin "${{ env.RELEASE_BRANCH }}" --tags
git checkout "${{ env.RELEASE_BRANCH }}"
# only fast-forward the merge
git merge --ff-only origin/main
git push origin "${{ env.RELEASE_BRANCH }}" --tags
File renamed without changes.
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

106 changes: 106 additions & 0 deletions cliff.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# git-cliff ~ configuration file
# https://git-cliff.org/docs/configuration

[changelog]
# A Tera template to be rendered as the changelog's header.
# See https://keats.github.io/tera/docs/#introduction
header = """
# Changelog
"""
# A Tera template to be rendered for each release in the changelog.
# See https://keats.github.io/tera/docs/#introduction
body = """
{%- macro remote_url() -%}
https://github.com/datadog/libdatadog
{%- endmacro -%}

{% macro print_commit(commit, strip_body=false) -%}
- {% if commit.scope %}*({{ commit.scope }})* {% endif %}\
{% if commit.breaking %}[**breaking**] {% endif %}\
{% if strip_body %}{{ commit.message | split(pat="\n") | first | upper_first }}{% else %}{{ commit.message | upper_first }}{% endif %} - \
([{{ commit.id | truncate(length=7, end="") }}]({{ self::remote_url() }}/commit/{{ commit.id }}))\
{% endmacro -%}

{% if version %}\
{% if version is containing("-v") %}
{% set version_crate = version | split(pat="-v") | last %}
{% else %}
{% set version_crate = version | trim_start_matches(pat="v") %}
{% endif %}
{% if previous.version %}\
## [{{ version_crate }}]\
({{ self::remote_url() }}/compare/{{ previous.version }}..{{ version }}) - {{ timestamp | date(format="%Y-%m-%d") }}
{% else %}\
## [{{ version_crate }}] - {{ timestamp | date(format="%Y-%m-%d") }}
{% endif %}\
{% else %}\
## [unreleased]
{% endif %}\

{% for group, commits in commits | group_by(attribute="group") %}
### {{ group | striptags | trim | upper_first }}
{%- set is_others = group is containing("Changed") %}
{% for commit in commits
| filter(attribute="scope")
| sort(attribute="scope") %}
{{ self::print_commit(commit=commit, strip_body=is_others) }}
{%- endfor %}
{% for commit in commits %}
{%- if not commit.scope -%}
{{ self::print_commit(commit=commit, strip_body=is_others) }}
{% endif -%}
{% endfor -%}
{% endfor -%}


"""
# A Tera template to be rendered as the changelog's footer.
# See https://keats.github.io/tera/docs/#introduction
footer = """

"""
# Remove leading and trailing whitespaces from the changelog's body.
trim = true
# An array of regex based postprocessors to modify the changelog.
postprocessors = [
# Replace the placeholder `<REPO>` with a URL.
{ pattern = '<REPO>', replace = "https://github.com/datadog/libdatadog" }, # replace repository URL
]

[git]
# Parse commits according to the conventional commits specification.
# See https://www.conventionalcommits.org
conventional_commits = true
# Exclude commits that do not match the conventional commits specification.
filter_unconventional = false
# Split commits on newlines, treating each line as an individual commit.
split_commits = false
# An array of regex based parsers to modify commit messages prior to further processing.
commit_preprocessors = [
# Replace issue numbers with link templates to be updated in `changelog.postprocessors`.
{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](<REPO>/issues/${2}))" },
]
# An array of regex based parsers for extracting data from the commit message.
# Assigns commits to groups.
# Optionally sets the commit's scope and can decide to exclude commits from further processing.
commit_parsers = [
{ message = "^feat", group = "<!-- A -->Added" },
{ message = "^fix", group = "<!-- C -->Fixed" },
{ message = "^refactor\\(clippy\\)", skip = true },
{ message = "^chore\\(release\\): prepare for", skip = true },
{ message = "^chore: Release", skip = true },
{ message = "^chore\\(deps.*\\)", skip = true },
{ message = "^chore\\(pr\\)", skip = true },
{ message = "^chore\\(pull\\)", skip = true },
{ message = "^chore\\(npm\\).*yarn\\.lock", skip = true },
{ message = ".*", group = "<!-- B -->Changed" },
]
# Prevent commits that are breaking from being excluded by commit parsers.
protect_breaking_commits = false
# Exclude commits that are not matched by any commit parser.
filter_commits = false
# Order releases topologically instead of chronologically.
topo_order = false
# Order of commits in each group/release within the changelog.
# Allowed values: newest, oldest
sort_commits = "newest"
1 change: 1 addition & 0 deletions datadog-ipc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# datadog-ipc
2 changes: 1 addition & 1 deletion libdd-common-ffi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ build_common = { path = "../build-common" }
anyhow = "1.0"
chrono = { version = "0.4.38", features = ["std"] }
crossbeam-queue = "0.3.11"
libdd-common = { version = "1.0.0", path = "../libdd-common" }
libdd-common = { version = "1.1.0", path = "../libdd-common" }
hyper = { workspace = true}
serde = "1.0"

Expand Down
14 changes: 14 additions & 0 deletions libdd-common/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# Changelog



## [1.1.0](https://github.com/datadog/libdatadog/compare/libdd-common-v1.0.0..libdd-common-v1.1.0) - 2026-01-22

### Added

- *(profiling)* Simpler API for profile exporter ([#1423](https://github.com/datadog/libdatadog/issues/1423)) - ([0d4ebbe](https://github.com/datadog/libdatadog/commit/0d4ebbe55ab841c2af8db41da74597c007375f0e))

### Changed

- *(profiling)* [**breaking**] Use reqwest instead of hyper for exporter ([#1444](https://github.com/datadog/libdatadog/issues/1444)) - ([39c7829](https://github.com/datadog/libdatadog/commit/39c7829592142d8fc8e8988b3631208e2d9ad1cc))
- Add changelog for every published crate ([#1396](https://github.com/datadog/libdatadog/issues/1396)) - ([5c4a024](https://github.com/datadog/libdatadog/commit/5c4a024598d6fe6cbd93a3e3dc9882848912064f))
- Don't panic if CryptoProvider already installed ([#1391](https://github.com/datadog/libdatadog/issues/1391)) - ([2f641ea](https://github.com/datadog/libdatadog/commit/2f641eae3708c34e4adfe62c9d477e665da4f12e))

## 1.0.0 - 2025-11-14

Initial release.
Loading