[PROF-15176] Add automated GitHub release workflow + bump to 0.3.0#62
Conversation
Adds .github/workflows/release.yml triggered on v*.*.* tag push: - Validates tag matches Version.h before doing any work - Builds Release on windows-2022 (same cmake invocation as test.yml, plus -DDD_WIN_PROF_BUILD_OBFUSCATION=ON) - Assembles dd-win-prof.zip matching v0.2.0's hand-packaged layout - Creates a draft GitHub Release with auto-generated notes and uploads the zip; left as draft so the maintainer can edit notes and publish Also bumps src/dd-win-prof/version.h from 0.1.0 to 0.3.0; v0.2.0 was released without bumping this and the new workflow's assertion step prevents that drift recurring. Pattern modeled on DataDog/java-profiler's gh_release.yml + update_assets.yml, collapsed into a single workflow since dd-win-prof builds artifacts in CI rather than fetching from a registry.
…ase zip Apache 2.0 §4 requires distributing LICENSE + NOTICE alongside any redistributed binary. The release zip ships libdatadog's datadog_profiling_ffi.dll (Apache 2.0) and dd-win-prof.dll, which statically links spdlog + bundled fmt (MIT). Add to the zip: LICENSE (dd-win-prof, Apache 2.0) NOTICE (dd-win-prof attribution) LICENSE-3rdparty.csv (canonical manifest) licenses/libdatadog-LICENSE licenses/spdlog-LICENSE
The release workflow's staging step was doing build-system-shaped work:
knowing where each artifact lives in the build tree, where headers and
license files live in the source tree, and what the on-disk layout of
the release should be. Move all of that into install() rules:
- src/dd-win-prof/CMakeLists.txt: install dd-win-prof.{dll,lib,pdb,h}
+ the vendored datadog_profiling_ffi.{dll,pdb} under Profiler/.
Config-aware via $<LOWER_CASE:$<CONFIG>> so 'cmake --install --config
Debug' would pick up the debug FFI variant.
- obfuscation/ObfSymbols/CMakeLists.txt: install ObfSymbols.exe under
Obfuscation/.
- CMakeLists.txt: install LICENSE, NOTICE, LICENSE-3rdparty.csv at the
package root, plus the upstream libdatadog and spdlog license texts
under licenses/. Gated on DD_WIN_PROF_IS_TOPLEVEL so consuming
projects that pull dd-win-prof in via add_subdirectory don't inherit
our top-level license install rules.
release.yml's 'Stage release assets' step collapses to a single
'cmake --install ... --prefix <stage>/dd-win-prof' + Compress-Archive.
Anyone with the repo can now reproduce the exact release layout locally
with 'cmake --install build --prefix foo/'.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0344765825
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Two new subsections under 'How to build dd-win-prof': - 'Packaging a release' documents the cmake --install invocation that reproduces the release zip layout locally, and points at the install() rules as the source of truth for the layout. - 'Cutting a release' walks through the version bump + tag push flow that drives release.yml, including the workflow_dispatch escape hatch for re-uploading assets without re-tagging.
cmake --install for the release package was failing because googletest's own install rules tried to install gtest.lib from a path that doesn't exist with our build layout, and would have also dropped gtest/spdlog headers into our release prefix regardless. Set the upstream-provided knobs (INSTALL_GTEST=OFF, SPDLOG_INSTALL=OFF) before FetchContent_MakeAvailable so only our own install() rules contribute to the release zip.
The previous install rules referenced third-party/libdatadog-x64-windows/LICENSE
and third-party/spdlog/LICENSE -- paths that only exist as stale local
vendoring leftovers, not in the git index. On a clean checkout cmake
--install failed with 'file INSTALL cannot find'.
The repo already has a tracked, canonical license layout: LICENSE +
NOTICE at the root, LICENSE-3rdparty.csv enumerating third-party
components, and licenses/{MIT,BSD-3-Clause}.txt with the corresponding
license texts. Install the whole licenses/ directory into the package
instead.
The inline pwsh block in release.yml was not runnable locally. Move
the parsing + comparison into scripts/check-version.ps1 -Tag <vX.Y.Z>
and have the workflow invoke it. Developers can now run the same
check before tagging:
.\scripts\check-version.ps1 -Tag v0.3.0
The repo's default GITHUB_TOKEN is org-capped to 'contents: read', so
'gh release create' would 403 even with workflow-declared
'contents: write'. Federate an elevated token via Octo-STS instead.
- .github/chainguard/self.release.build-and-release.sts.yaml: trust
policy. Matches a vX.Y.Z tag push or workflow_dispatch from main,
locked to .github/workflows/release.yml as the calling workflow,
granting contents: write.
- release.yml: drop contents: write from the job-level permissions
(no longer needed on GITHUB_TOKEN), add id-token: write so the runner
can mint the OIDC token, add a DataDog/dd-octo-sts-action step, and
use ${{ steps.octo-sts.outputs.token }} for the gh release calls.
Naming convention and policy shape mirror DataDog/java-profiler's
existing octo-sts integrations (approve-trivial, dependabot-automerge).
Per the dd-octo-sts authoritative guide:
- Rename file to follow {source}.{environment}.{action}.{context} naming:
self.release.build-and-release.sts.yaml
-> self.github.release.publish.sts.yaml
- Add 'Policy for: ...' header comment so reviewers immediately see the
source workflow and job.
- Use [0-9]+ instead of \d+ in patterns (matches guide examples).
- Add the 'repository' claim alongside event_name / ref / job_workflow_ref
for defense in depth, and tighten job_workflow_ref to the same ref set
as subject_pattern.
- Keep claim_pattern keys in alphabetical order per the style guide.
dd-octo-sts-action is already pinned to the latest release (v1.0.4,
SHA 96a25462dbcb10ebf0bfd6e2ccc917d2ab235b9a).
git tag -s produces a signed annotated tag using the SSH key configured globally (gpg.format=ssh). Lightweight unsigned tags are discouraged for releases; downstream consumers can verify provenance from the signature.
main always sits at the version about to be released, so the tag points at main as-is. The version.h bump becomes a follow-up PR that moves main onto the next dev version, rather than a precondition for the tag. This keeps the path-to-release as short as 'tag and push'.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e10cb06b75
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } | ||
|
|
||
| $zipPath = Join-Path $stagingRoot "dd-win-prof.zip" | ||
| Compress-Archive -Path $pkgDir -DestinationPath $zipPath |
There was a problem hiding this comment.
Exclude the staging folder from the release archive
On the Windows release job, Compress-Archive -Path $pkgDir archives the directory itself; Microsoft documents that a Path without a wildcard includes the root directory, while C:\Reference\* excludes it (https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.archive/compress-archive#example-3-compress-a-directory-that-includes-the-root-directory). Because $pkgDir is already named dd-win-prof, the uploaded dd-win-prof.zip will extract to dd-win-prof\LICENSE, dd-win-prof\Profiler\... instead of the documented v0.2.0-compatible root layout (LICENSE, Profiler\...), so consumers/scripts that unzip the asset and look for files at the archive root will fail.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Looks like we have the same structure as before. Not an issue.
|
|
||
| #define DLL_VERSION_MAJOR 0 | ||
| #define DLL_VERSION_MINOR 1 | ||
| #define DLL_VERSION_MINOR 3 |
There was a problem hiding this comment.
Keep VERSIONINFO in sync with the bumped release
When the v0.3.0 release is built, this bump updates the profiler header and lets scripts/check-version.ps1 pass, but the Windows resource compiled into dd-win-prof.dll still hard-codes 0.2.0.0 in src/dd-win-prof/Resource.rc for FILEVERSION, PRODUCTVERSION, and the string values. Users or deployment tooling that inspect the DLL's file/product version will see a v0.2.0 binary inside the v0.3.0 release artifact, and the new release gate won't catch that drift because it only parses version.h.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
ok, this is real and needs a follow up PR
Description
Adds an automated release workflow and bumps to
0.3.0. Pushing avX.Y.Ztag now produces a draft GitHub Release withdd-win-prof.zipattached.Changes:
.github/workflows/release.yml— onv*.*.*tag push (orworkflow_dispatchagainst an existing tag), checksVersion.hmatches the tag, builds Release onwindows-2022(same cmake invocation astest.yml+-DDD_WIN_PROF_BUILD_OBFUSCATION=ON), runscmake --install, zips, and creates a draft release with auto-generated notes..github/chainguard/self.github.release.publish.sts.yaml— Octo-STS trust policy. The repo's defaultGITHUB_TOKENis capped tocontents: read, so the workflow federates an elevated token viaDataDog/dd-octo-sts-action@96a25462...(v1.0.4, pinned) and uses it forgh release create. Policy is narrowly scoped to avX.Y.Ztag push or aworkflow_dispatchfrommain, locked torelease.yml, grantingcontents: writeonly. Naming and shape follow the dd-octo-sts conventions ({source}.{environment}.{action}.{context}.sts.yaml).install()rules insrc/dd-win-prof/,obfuscation/ObfSymbols/, and the top-levelCMakeLists.txt. The workflow just drives them — file paths and on-disk layout are owned by CMake, not the YAML. Reproducible locally withcmake --install build --config Release --prefix .\stage\dd-win-prof.LICENSE,NOTICE,LICENSE-3rdparty.csv, and the trackedlicenses/directory in the zip. v0.2.0 didn't have these.INSTALL_GTEST=OFF) and spdlog (SPDLOG_INSTALL=OFF) so they don't pollute the release prefix.scripts/check-version.ps1— extracted the tag-vs-version.hcheck so it's runnable locally (.\scripts\check-version.ps1 -Tag v0.3.0).src/dd-win-prof/version.hbumped0.1.0→0.3.0(v0.2.0 shipped without bumping; the new assertion prevents the drift recurring).Final zip layout (strict superset of v0.2.0 — outer
dd-win-prof/wrapper preserved, no binaries removed, licensing files added):Motivation
v0.1.0 and v0.2.0 were built and packaged manually, and v0.2.0 shipped with a stale
version.hand no LICENSE/NOTICE in the zip. Automating the release closes both gaps and gives us a reproducible artifact pipeline. Packaging logic lives in CMake so anyone can repro the release tree locally — the workflow's role is just trigger + upload.Ticket: PROF-15176 (parent epic: PROF-14955).
Testing
test.ymlCI runs unchanged on this PR.cmake --install build --config Release --prefix .\stage\dd-win-profreproduces the expected layout locally on Windows.End-to-end validation of the tag-triggered path (Octo-STS federation +
gh release create) happens on the v0.3.0 tag push.Checklist