diff --git a/.github/workflows/shared-publish-java-to-docker-versioned.yaml b/.github/workflows/shared-publish-java-to-docker-versioned.yaml
index 813ef6cc..75d2395a 100644
--- a/.github/workflows/shared-publish-java-to-docker-versioned.yaml
+++ b/.github/workflows/shared-publish-java-to-docker-versioned.yaml
@@ -224,28 +224,12 @@ jobs:
subject_name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}${{ inputs.append_image_name }}
subject_digest: ${{ steps.push.outputs.digest }}
- - name: Build Changelog
- id: github_release
- if: ${{ steps.checkRelease.outputs.is_release == 'true' }}
- uses: mikepenz/release-changelog-builder-action@32e3c96f29a6532607f638797455e9e98cfc703d # v4
- with:
- toTag: v${{ steps.version.outputs.new_version }}
- configurationJson: |
- {
- "template": "#{{CHANGELOG}}\n## Installation\n```\ndocker pull ${{ steps.meta.outputs.tags }}\n```\n\n## Image reference to deploy: \n```\n${{ steps.updatePom.outputs.image_tag }}\n```\n\n## Changelog\n#{{UNCATEGORIZED}}",
- "pr_template": " - #{{TITLE}} - ( PR: ##{{NUMBER}} )"
- }
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-
- - name: Delete Draft Releases
- if: ${{ steps.checkRelease.outputs.is_release == 'true' }}
- uses: IABTechLab/uid2-shared-actions/actions/delete_draft_releases@v3
-
- name: Create Release
- if: ${{ steps.checkRelease.outputs.is_release == 'true' }}
- uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2
+ uses: IABTechLab/uid2-shared-actions/actions/shared_create_releases@v3
with:
- name: v${{ steps.version.outputs.new_version }}
- body: ${{ steps.github_release.outputs.changelog }}
- draft: true
+ is_release: ${{ steps.checkRelease.outputs.is_release }}
+ new_version: ${{ steps.version.outputs.new_version }}
+ tags: ${{ steps.meta.outputs.tags }}
+ image_tag: ${{ steps.updatePom.outputs.image_tag }}
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ publish_platform: Docker
diff --git a/.github/workflows/shared-publish-to-docker-versioned.yaml b/.github/workflows/shared-publish-to-docker-versioned.yaml
index 559b1d94..8efbdea5 100644
--- a/.github/workflows/shared-publish-to-docker-versioned.yaml
+++ b/.github/workflows/shared-publish-to-docker-versioned.yaml
@@ -80,7 +80,7 @@ jobs:
- name: Create Release
id: github_release
- uses: IABTechLab/uid2-shared-actions/actions/shared_create_releases@v2
+ uses: IABTechLab/uid2-shared-actions/actions/shared_create_releases@v3
with:
is_release: ${{ steps.setup.outputs.is_release }}
new_version: ${{ inputs.new_version }}
diff --git a/.github/workflows/shared-publish-to-ios-version.yaml b/.github/workflows/shared-publish-to-ios-version.yaml
index e56bce26..e34cd234 100644
--- a/.github/workflows/shared-publish-to-ios-version.yaml
+++ b/.github/workflows/shared-publish-to-ios-version.yaml
@@ -98,22 +98,10 @@ jobs:
tag: v${{ steps.version.outputs.new_version }}
github_token: ${{ inputs.merge_environment != '' && secrets.GH_MERGE_TOKEN || '' }}
- - name: Build Changelog
- id: github_release
- uses: mikepenz/release-changelog-builder-action@32e3c96f29a6532607f638797455e9e98cfc703d # v4
- with:
- toTag: v${{ steps.version.outputs.new_version }}
- configurationJson: |
- {
- "template": "#{{CHANGELOG}}\n## Changelog\n#{{UNCATEGORIZED}}",
- "pr_template": " - #{{TITLE}} - ( PR: ##{{NUMBER}} )"
- }
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-
- name: Create Release
- uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2
+ uses: IABTechLab/uid2-shared-actions/actions/shared_create_releases@v3
with:
- name: v${{ steps.version.outputs.new_version }}
- body: ${{ steps.github_release.outputs.changelog }}
- draft: true
+ is_release: ${{ steps.checkRelease.outputs.is_release }}
+ new_version: ${{ steps.version.outputs.new_version }}
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ publish_platform: iOS
diff --git a/.github/workflows/shared-publish-to-maven-versioned.yaml b/.github/workflows/shared-publish-to-maven-versioned.yaml
index 1fe1b952..7888ae80 100644
--- a/.github/workflows/shared-publish-to-maven-versioned.yaml
+++ b/.github/workflows/shared-publish-to-maven-versioned.yaml
@@ -159,24 +159,27 @@ jobs:
tag: v${{ steps.version.outputs.new_version }}
github_token: ${{ inputs.merge_environment != '' && secrets.GH_MERGE_TOKEN || '' }}
- - name: Build Changelog
- id: github_release
- if: ${{ env.IS_RELEASE == 'true' }}
- uses: mikepenz/release-changelog-builder-action@32e3c96f29a6532607f638797455e9e98cfc703d # v4
- with:
- toTag: v${{ steps.version.outputs.new_version }}
- configurationJson: |
- {
- "template": "#{{CHANGELOG}}\n## Maven\n```\n\n com.uid2\n ${{ env.REPO }}\n ${{ steps.version.outputs.new_version }}\n\n```\n\n## Jar Files\n- [${{ env.REPO }}-${{ steps.version.outputs.new_version }}.jar](https://repo1.maven.org/maven2/com/uid2/${{ env.REPO }}/${{ steps.version.outputs.new_version }}/${{ env.REPO }}-${{ steps.version.outputs.new_version }}.jar)\n\n## Changelog\n#{{UNCATEGORIZED}}",
- "pr_template": " - #{{TITLE}} - ( PR: ##{{NUMBER}} )"
- }
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: Extract Maven artifactId
+ id: package_name
+ run: |
+ # Maven artifactId comes from pom.xml, not the github repo name
+ # (e.g. uid2-attestation-azure repo publishes the `attestation-azure`
+ # artifact). Use `mvn help:evaluate` as the canonical source so
+ # release-notes install snippets match what `mvn deploy` actually
+ # published.
+ artifact_id=$(mvn -B -f "${{ inputs.working_dir }}/pom.xml" help:evaluate -Dexpression=project.artifactId -q -DforceStdout)
+ if [ -z "$artifact_id" ]; then
+ echo "ERROR: could not extract artifactId from ${{ inputs.working_dir }}/pom.xml" >&2
+ exit 1
+ fi
+ echo "Extracted Maven artifactId: $artifact_id"
+ echo "name=$artifact_id" >> "$GITHUB_OUTPUT"
- name: Create Release
- if: ${{ env.IS_RELEASE == 'true' }}
- uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2
+ uses: IABTechLab/uid2-shared-actions/actions/shared_create_releases@v3
with:
- name: v${{ steps.version.outputs.new_version }}
- body: ${{ steps.github_release.outputs.changelog }}
- draft: true
+ is_release: ${{ env.IS_RELEASE }}
+ new_version: ${{ steps.version.outputs.new_version }}
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ publish_platform: Maven
+ repo: ${{ steps.package_name.outputs.name }}
diff --git a/.github/workflows/shared-publish-to-nuget-versioned.yaml b/.github/workflows/shared-publish-to-nuget-versioned.yaml
index 19061075..b4a3b64a 100644
--- a/.github/workflows/shared-publish-to-nuget-versioned.yaml
+++ b/.github/workflows/shared-publish-to-nuget-versioned.yaml
@@ -107,24 +107,11 @@ jobs:
tag: v${{ steps.version.outputs.new_version }}
github_token: ${{ inputs.merge_environment != '' && secrets.GH_MERGE_TOKEN || '' }}
- - name: Build Changelog
- if: ${{ steps.checkRelease.outputs.is_release == 'true' }}
- id: github_release
- uses: mikepenz/release-changelog-builder-action@32e3c96f29a6532607f638797455e9e98cfc703d # v4
- with:
- toTag: v${{ steps.version.outputs.new_version }}
- configurationJson: |
- {
- "template": "#{{CHANGELOG}}\n## NuGet\n```\n\n com.uid2\n ${{ env.REPO }}\n ${{ steps.version.outputs.new_version }}\n\n```\n\n## Nuget Files\n- [UID2.Client.${{ steps.version.outputs.new_version }}.nupkg](https://www.nuget.org/packages/UID2.Client)\n\n## Changelog\n#{{UNCATEGORIZED}}",
- "pr_template": " - #{{TITLE}} - ( PR: ##{{NUMBER}} )"
- }
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-
- name: Create Release
- if: ${{ steps.checkRelease.outputs.is_release == 'true' }}
- uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2
+ uses: IABTechLab/uid2-shared-actions/actions/shared_create_releases@v3
with:
- name: v${{ steps.version.outputs.new_version }}
- body: ${{ steps.github_release.outputs.changelog }}
- draft: true
+ is_release: ${{ steps.checkRelease.outputs.is_release }}
+ new_version: ${{ steps.version.outputs.new_version }}
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ publish_platform: NuGet
+ repo: UID2.Client
diff --git a/.github/workflows/shared-publish-to-pypi-versioned.yaml b/.github/workflows/shared-publish-to-pypi-versioned.yaml
index d0a76467..4aea7a84 100644
--- a/.github/workflows/shared-publish-to-pypi-versioned.yaml
+++ b/.github/workflows/shared-publish-to-pypi-versioned.yaml
@@ -97,22 +97,26 @@ jobs:
tag: v${{ steps.version.outputs.new_version }}
github_token: ${{ inputs.merge_environment != '' && secrets.GH_MERGE_TOKEN || '' }}
- - name: Build Changelog
- id: github_release
- uses: mikepenz/release-changelog-builder-action@32e3c96f29a6532607f638797455e9e98cfc703d # v4
- with:
- toTag: v${{ steps.version.outputs.new_version }}
- configurationJson: |
- {
- "template": "#{{CHANGELOG}}\n## Pypi\n```\n\n com.uid2\n ${{ env.REPO }}\n ${{ steps.version.outputs.new_version }}\n\n```\n\n## Pypi Files\n- [uid2_client-${{ steps.version.outputs.new_version }}.tar.gz](https://pypi.org/project/uid2-client/)\n\n## Changelog\n#{{UNCATEGORIZED}}",
- "pr_template": " - #{{TITLE}} - ( PR: ##{{NUMBER}} )"
- }
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: Extract PyPI package name
+ id: package_name
+ run: |
+ # PyPI package name comes from pyproject.toml, not the github repo name
+ # (e.g. uid2-client-python repo publishes the `uid2-client` package).
+ # Read the top-level `name = "..."` field so release-notes install snippets
+ # match the real PyPI package, not the git repo.
+ name=$(grep -E '^\s*name\s*=' "${{ inputs.working_dir }}/pyproject.toml" | head -1 | cut -d '"' -f 2)
+ if [ -z "$name" ]; then
+ echo "ERROR: could not extract 'name' from ${{ inputs.working_dir }}/pyproject.toml" >&2
+ exit 1
+ fi
+ echo "Extracted PyPI package name: $name"
+ echo "name=$name" >> "$GITHUB_OUTPUT"
- name: Create Release
- uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2
+ uses: IABTechLab/uid2-shared-actions/actions/shared_create_releases@v3
with:
- name: v${{ steps.version.outputs.new_version }}
- body: ${{ steps.github_release.outputs.changelog }}
- draft: true
+ is_release: ${{ steps.checkRelease.outputs.is_release }}
+ new_version: ${{ steps.version.outputs.new_version }}
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ publish_platform: PyPI
+ repo: ${{ steps.package_name.outputs.name }}
diff --git a/README.md b/README.md
index 2b12b632..ce5d3cf5 100644
--- a/README.md
+++ b/README.md
@@ -4,6 +4,17 @@ This repo contains shared actions and workflows that are consumed by the other u
This simplifies the management and maintenance of the workflows.
+## Release notes
+
+All shared publish workflows generate release notes via the `actions/shared_create_releases` composite action, which wraps [`mikepenz/release-changelog-builder-action`](https://github.com/mikepenz/release-changelog-builder-action) (SHA-pinned). This is the canonical approach for this repo — chosen over GitHub-native auto-generated notes (`generate_release_notes: true`) because:
+
+- The native format hardcodes `* TITLE by @AUTHOR in #NUMBER`. Authors are noise to the public consumers of these releases; mikepenz's `pr_template` lets us emit `- TITLE - ( PR: #NUMBER )` instead.
+- The composite embeds a per-platform install snippet (`docker pull`, `pip install`, `dotnet add package`, Maven ``) above the changelog.
+
+`shared_create_releases` supports `publish_platform` values `Docker`, `Maven`, `PyPI`, `NuGet`, `iOS`. It runs three steps internally: Build Changelog (mikepenz) → Delete Draft Releases → Create Release (softprops, draft). When `is_release` is `false` (Snapshot/pre-release) the action is a no-op, so callers can invoke it unconditionally.
+
+When adding a new publish workflow, call `IABTechLab/uid2-shared-actions/actions/shared_create_releases@v3` rather than inlining mikepenz. Do not set `continue-on-error: true` on it — the workflow must fail if release-notes generation fails. Decision documented in [UID2-6762](https://thetradedesk.atlassian.net/browse/UID2-6762).
+
## Tips and tricks
If you're trying to do something that should be simple, but can't find something that quite supports what you're trying to do, the [GitHub Script action](https://github.com/actions/github-script) gives you an authenticated GitHub API client and you can just provide a JavaScript script. For an example, see the "Tag commit" step in the [Commit, PR, and Merge](actions\commit-pr-and-merge\action.yaml) shared action.
diff --git a/actions/shared_create_releases/action.yaml b/actions/shared_create_releases/action.yaml
index 83aae3ec..592fbe3c 100644
--- a/actions/shared_create_releases/action.yaml
+++ b/actions/shared_create_releases/action.yaml
@@ -1,39 +1,43 @@
name: Create releases
-description: Create releases and build changelogs
+description: Build the release-notes changelog, delete stale draft releases, and create a draft GitHub Release for a published artifact. Canonical release-notes pipeline for this repo — every shared publish workflow should call this action rather than inlining mikepenz/release-changelog-builder. Decision and rationale documented in UID2-6762.
inputs:
is_release:
- description: True if a release should be created
+ description: True if a release should be created (Patch/Minor/Major). When false, the action is a no-op — safe to call unconditionally for Snapshot/pre-release builds.
default: 'false'
new_version:
- description: The new version number to be incremented to
+ description: The new version number being released (without leading v).
required: true
- tags:
- description: The docker image tags
- default: ''
- image_tag:
- description: The image tag for the new version
- default: ''
github_token:
- description: The github token to login to Docker container
+ description: GitHub token used by mikepenz to read merged PRs and by softprops to create the draft release.
required: true
publish_platform:
- description: The platform we are publishing to. Must be one of [Docker or Maven]
+ description: Must be one of [Docker, Maven, PyPI, NuGet, iOS].
required: true
repo:
- description: The repo that publishing to.
+ description: Package/artifact identifier. Used by Maven (artifactId in the dependency snippet and jar URL), PyPI (pip install target and PyPI page link), and NuGet (package id). Not used by Docker or iOS.
+ default: ''
+ tags:
+ description: Comma-separated docker image tags (Docker only). Typically the output of docker/metadata-action.
+ default: ''
+ image_tag:
+ description: The image reference shown in the release notes as the deploy target (Docker only).
+ default: ''
+ from_tag:
+ description: Optional. Override mikepenz's auto-detection of the previous tag. Useful when auto-detection is confused by non-sequential tag names (e.g. when v3.7 and v3.70 coexist) or when manually backfilling notes for a specific tag range. Leave empty in normal release flows.
default: ''
runs:
- using: "composite"
+ using: "composite"
steps:
- name: Build Docker Changelog
id: github_release_docker
- if: ${{ inputs.is_release == 'true' && inputs.publish_platform == 'Docker'}}
+ if: ${{ inputs.is_release == 'true' && inputs.publish_platform == 'Docker' }}
uses: mikepenz/release-changelog-builder-action@32e3c96f29a6532607f638797455e9e98cfc703d # v4
with:
toTag: v${{ inputs.new_version }}
+ fromTag: ${{ inputs.from_tag }}
configurationJson: |
{
"template": "#{{CHANGELOG}}\n## Installation\n```\ndocker pull ${{ inputs.tags }}\n```\n\n## Image reference to deploy: \n```\n${{ inputs.image_tag }}\n```\n\n## Changelog\n#{{UNCATEGORIZED}}",
@@ -44,10 +48,11 @@ runs:
- name: Build Maven Changelog
id: github_release_maven
- if: ${{ inputs.is_release == 'true' && inputs.publish_platform == 'Maven'}}
+ if: ${{ inputs.is_release == 'true' && inputs.publish_platform == 'Maven' }}
uses: mikepenz/release-changelog-builder-action@32e3c96f29a6532607f638797455e9e98cfc703d # v4
with:
toTag: v${{ inputs.new_version }}
+ fromTag: ${{ inputs.from_tag }}
configurationJson: |
{
"template": "#{{CHANGELOG}}\n## Maven\n```\n\n com.uid2\n ${{ inputs.repo }}\n ${{ inputs.new_version }}\n\n```\n\n## Jar Files\n- [${{ inputs.repo }}-${{ inputs.new_version }}.jar](https://repo1.maven.org/maven2/com/uid2/${{ inputs.repo }}/${{ inputs.new_version }}/${{ inputs.repo }}-${{ inputs.new_version }}.jar)\n\n## Changelog\n#{{UNCATEGORIZED}}",
@@ -56,18 +61,59 @@ runs:
env:
GITHUB_TOKEN: ${{ inputs.github_token }}
- - name: Create Docker Release
- if: ${{ inputs.is_release == 'true' && inputs.publish_platform == 'Docker' }}
- uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2
+ - name: Build PyPI Changelog
+ id: github_release_pypi
+ if: ${{ inputs.is_release == 'true' && inputs.publish_platform == 'PyPI' }}
+ uses: mikepenz/release-changelog-builder-action@32e3c96f29a6532607f638797455e9e98cfc703d # v4
with:
- name: v${{ inputs.new_version }}
- body: ${{ steps.github_release_docker.outputs.changelog }}
- draft: true
+ toTag: v${{ inputs.new_version }}
+ fromTag: ${{ inputs.from_tag }}
+ configurationJson: |
+ {
+ "template": "#{{CHANGELOG}}\n## PyPI\n```\npip install ${{ inputs.repo }}==${{ inputs.new_version }}\n```\n\n## PyPI page\n- [${{ inputs.repo }} ${{ inputs.new_version }}](https://pypi.org/project/${{ inputs.repo }}/${{ inputs.new_version }}/)\n\n## Changelog\n#{{UNCATEGORIZED}}",
+ "pr_template": " - #{{TITLE}} - ( PR: ##{{NUMBER}} )"
+ }
+ env:
+ GITHUB_TOKEN: ${{ inputs.github_token }}
+
+ - name: Build NuGet Changelog
+ id: github_release_nuget
+ if: ${{ inputs.is_release == 'true' && inputs.publish_platform == 'NuGet' }}
+ uses: mikepenz/release-changelog-builder-action@32e3c96f29a6532607f638797455e9e98cfc703d # v4
+ with:
+ toTag: v${{ inputs.new_version }}
+ fromTag: ${{ inputs.from_tag }}
+ configurationJson: |
+ {
+ "template": "#{{CHANGELOG}}\n## NuGet\n```\ndotnet add package ${{ inputs.repo }} --version ${{ inputs.new_version }}\n```\n\n## NuGet page\n- [${{ inputs.repo }} ${{ inputs.new_version }}](https://www.nuget.org/packages/${{ inputs.repo }}/${{ inputs.new_version }})\n\n## Changelog\n#{{UNCATEGORIZED}}",
+ "pr_template": " - #{{TITLE}} - ( PR: ##{{NUMBER}} )"
+ }
+ env:
+ GITHUB_TOKEN: ${{ inputs.github_token }}
+
+ - name: Build iOS Changelog
+ id: github_release_ios
+ if: ${{ inputs.is_release == 'true' && inputs.publish_platform == 'iOS' }}
+ uses: mikepenz/release-changelog-builder-action@32e3c96f29a6532607f638797455e9e98cfc703d # v4
+ with:
+ toTag: v${{ inputs.new_version }}
+ fromTag: ${{ inputs.from_tag }}
+ configurationJson: |
+ {
+ "template": "#{{CHANGELOG}}\n## Changelog\n#{{UNCATEGORIZED}}",
+ "pr_template": " - #{{TITLE}} - ( PR: ##{{NUMBER}} )"
+ }
+ env:
+ GITHUB_TOKEN: ${{ inputs.github_token }}
+
+ - name: Delete Draft Releases
+ if: ${{ inputs.is_release == 'true' }}
+ uses: IABTechLab/uid2-shared-actions/actions/delete_draft_releases@v3
- - name: Create Maven Release
- if: ${{ inputs.is_release == 'true' && inputs.publish_platform == 'Maven'}}
+ - name: Create Release
+ if: ${{ inputs.is_release == 'true' }}
uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2
with:
name: v${{ inputs.new_version }}
- body: ${{ steps.github_release_maven.outputs.changelog }}
+ body: ${{ inputs.publish_platform == 'Docker' && steps.github_release_docker.outputs.changelog || inputs.publish_platform == 'Maven' && steps.github_release_maven.outputs.changelog || inputs.publish_platform == 'PyPI' && steps.github_release_pypi.outputs.changelog || inputs.publish_platform == 'NuGet' && steps.github_release_nuget.outputs.changelog || steps.github_release_ios.outputs.changelog }}
draft: true