Skip to content
Merged
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
29 changes: 29 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,35 @@ on:
- cron: '0 0 * * *' # Runs at midnight UTC every day

jobs:
test-default-datadog-ci-version:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check that the default datadog-ci version is pinned
run: |
set -euo pipefail
default_version=$(ruby -ryaml -e 'puts YAML.load_file("action.yaml").fetch("inputs").fetch("datadog-ci-version").fetch("default")')
if [[ ! "$default_version" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Expected datadog-ci-version default to be an exact release tag, got '$default_version'"
exit 1
fi
- name: Check local release helper scripts
run: |
set -euo pipefail
bash -n scripts/bump-datadog-ci-version.sh
bash -n scripts/create-datadog-ci-bump-pr.sh
bash -n scripts/release-datadog-ci-bump.sh

tmpdir=$(mktemp -d)
cp action.yaml README.md "$tmpdir"/
mkdir "$tmpdir/scripts"
cp scripts/bump-datadog-ci-version.sh "$tmpdir/scripts"/
cd "$tmpdir"

scripts/bump-datadog-ci-version.sh v5.99.1
ruby -ryaml -e 'abort unless YAML.load_file("action.yaml").fetch("inputs").fetch("datadog-ci-version").fetch("default") == "v5.99.1"'
grep -q '| `datadog-ci-version` |.*| `v5.99.1`' README.md

test:
runs-on: ubuntu-latest
steps:
Expand Down
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,15 @@ The action has the following options:
| `service` | Service name to use with the uploaded test results. | False | |
| `env` | Optional environment to add to the tests | False | |
| `logs` | When set to "true" enables forwarding content from the XML reports as Logs. The content inside `<system-out>`, `<system-err>`, and `<failure>` is collected as logs. Logs from elements inside a `<testcase>` are automatically connected to the test. | False | |
| `datadog-ci-version` | Version of datadog-ci to install. Use a major version like `v5` to get the latest release within that major version, or a specific tag like `v5.6.0` to pin. Legacy npm semver syntax (`^`, `~`, `>=`, `latest`) is still supported but deprecated. | False | `v5` |
| `datadog-ci-version` | Version of datadog-ci to install. Defaults to the pinned datadog-ci release shipped with this action version. Use a major version like `v5` to get the latest release within that major version, or a specific tag like `v5.6.0` to pin. Legacy npm semver syntax (`^`, `~`, `>=`, `latest`) is still supported but deprecated. | False | `v5.14.0` |
| `github-token` | GitHub token to use for authenticated datadog-ci release resolution. Defaults to the workflow `github.token` when omitted. | False | `github.token` |
| `extra-args` | Extra args to be passed to the datadog-ci junit upload command. | False | |

This action passes the workflow `github.token` to the install step by default. That is primarily useful when `datadog-ci-version` uses a floating release selector such as `v5`, because GitHub release resolution can then be authenticated. To avoid depending on latest-within-major resolution, pin an exact `datadog-ci` version such as `v5.6.0` or `5.6.0`.
By default, this action installs the exact `datadog-ci` release pinned by the action version you use. To receive `datadog-ci` updates, update `datadog/junit-upload-github-action` to a newer release or use
the `datadog-ci-version` configuration to specify the version or range.

This action passes the workflow `github.token` to the install step by default. That is primarily useful when `datadog-ci-version` uses a floating release selector such as `v5`, because GitHub release resolution can then be authenticated.

## Maintainer release flow

See [RELEASE.md](RELEASE.md) for the local `gh`-based process used to bump `datadog-ci` and release this action.
44 changes: 44 additions & 0 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Release Process

This repository ships a composite GitHub Action. Releases are Git tags: immutable semver tags such as `v3.0.1`, plus a moving major tag such as `v3`.

## Bump datadog-ci

Run the bump helper from a clean working tree:

```bash
scripts/create-datadog-ci-bump-pr.sh
```

The script uses `gh` to check the latest `DataDog/datadog-ci` release. If that release is newer than the default in `action.yaml`, it creates a branch, updates `action.yaml` and `README.md`, pushes the branch, creates the `datadog-ci-version-bump` label if needed, and opens a PR with that label.

To test a specific version instead of the latest release:

```bash
scripts/create-datadog-ci-bump-pr.sh v5.14.0
```

Review and merge the PR normally.

## Release the action

After a `datadog-ci-version-bump` PR is merged, run:

```bash
scripts/release-datadog-ci-bump.sh
```

The script fetches `main` and tags, finds the latest merged PR with the `datadog-ci-version-bump` label that is on `main` but not included in the latest immutable action tag, and releases that merge commit. A release creates the next patch tag, updates the moving major tag, and creates a GitHub Release.

Preview the release without creating tags or a GitHub Release:

```bash
scripts/release-datadog-ci-bump.sh --dry-run
```

If multiple bump PRs were merged without releases, the script warns and releases only the latest one. To intentionally release an older merge commit separately, stop and pass a specific PR number or commit SHA before releasing the latest one:

```bash
scripts/release-datadog-ci-bump.sh --pr 123
scripts/release-datadog-ci-bump.sh --sha abc1234
```
4 changes: 2 additions & 2 deletions action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ inputs:
description: Set to "true" to enable forwarding content from XML reports as logs.
datadog-ci-version:
required: false
description: Version of datadog-ci to install. Use a major version like `v5` to get the latest release within that major version, or a specific tag like `v5.6.0` to pin. Legacy npm semver syntax (^, ~, >=, latest) is still supported but deprecated.
default: "v5"
description: Version of datadog-ci to install. Defaults to the pinned datadog-ci release shipped with this action version. Use a major version like `v5` to get the latest release within that major version, or a specific tag like `v5.6.0` to pin. Legacy npm semver syntax (^, ~, >=, latest) is still supported but deprecated.
default: "v5.14.0"
github-token:
required: false
default: ""
Expand Down
30 changes: 30 additions & 0 deletions scripts/bump-datadog-ci-version.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/usr/bin/env bash
set -euo pipefail

if [[ $# -ne 1 ]]; then
echo "Usage: $0 vX.Y.Z" >&2
exit 1
fi

version="$1"

if [[ ! "$version" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Expected an exact datadog-ci release tag like v5.13.1, got '$version'" >&2
exit 1
fi

ruby - "$version" <<'RUBY'
version = ARGV.fetch(0)

action_path = 'action.yaml'
action = File.read(action_path)
action_pattern = /(^ datadog-ci-version:\n(?:(?!^ [A-Za-z0-9_-]+:).*\n)*?^ default: )"v\d+\.\d+\.\d+"/
abort "Unable to find datadog-ci-version default in #{action_path}" unless action.match?(action_pattern)
File.write(action_path, action.sub(action_pattern) { "#{Regexp.last_match(1)}\"#{version}\"" })

readme_path = 'README.md'
readme = File.read(readme_path)
readme_pattern = /^(\| `datadog-ci-version` \|.*\| False\s+\| `)v\d+\.\d+\.\d+(`\s+\|)$/
abort "Unable to find datadog-ci-version default in #{readme_path}" unless readme.match?(readme_pattern)
File.write(readme_path, readme.sub(readme_pattern) { "#{Regexp.last_match(1)}#{version}#{Regexp.last_match(2)}" })
RUBY
136 changes: 136 additions & 0 deletions scripts/create-datadog-ci-bump-pr.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
#!/usr/bin/env bash
set -euo pipefail

usage() {
cat <<'EOF'
Usage: scripts/create-datadog-ci-bump-pr.sh [vX.Y.Z]

Checks the latest DataDog/datadog-ci release with gh, then opens a PR that bumps
the default datadog-ci-version when the release is newer than the current default.

Arguments:
vX.Y.Z Optional exact datadog-ci release tag to use instead of releases/latest.

Environment:
BASE_BRANCH Base branch for the PR. Defaults to main.
BRANCH_NAME Branch to create. Defaults to datadog-ci-bump/<version>.
BUMP_LABEL Label applied to the PR. Defaults to datadog-ci-version-bump.
REMOTE Git remote to push to. Defaults to origin.
REPO GitHub repo for gh commands. Defaults to gh repo view's repo.
EOF
}

if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
usage
exit 0
fi

if [[ $# -gt 1 ]]; then
usage >&2
exit 1
fi

for command in gh git ruby; do
if ! command -v "$command" >/dev/null 2>&1; then
echo "Missing required command: $command" >&2
exit 1
fi
done

if [[ -n "$(git status --porcelain)" ]]; then
echo "Working tree must be clean before creating a bump PR." >&2
exit 1
fi

gh auth status >/dev/null

base_branch="${BASE_BRANCH:-main}"
bump_label="${BUMP_LABEL:-datadog-ci-version-bump}"
remote="${REMOTE:-origin}"
repo="${REPO:-$(gh repo view --json nameWithOwner --jq '.nameWithOwner')}"
requested_version="${1:-}"

current_version=$(ruby -ryaml -e 'puts YAML.load_file("action.yaml").fetch("inputs").fetch("datadog-ci-version").fetch("default")')
if [[ -n "$requested_version" ]]; then
latest_version="$requested_version"
else
latest_version=$(gh api repos/DataDog/datadog-ci/releases/latest --jq '.tag_name')
fi

if [[ ! "$latest_version" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Expected an exact datadog-ci release tag like v5.13.1, got '$latest_version'" >&2
exit 1
fi

version_gt() {
local left="${1#v}"
local right="${2#v}"
local left_major left_minor left_patch right_major right_minor right_patch

IFS=. read -r left_major left_minor left_patch <<< "$left"
IFS=. read -r right_major right_minor right_patch <<< "$right"

(( left_major > right_major )) && return 0
(( left_major < right_major )) && return 1
(( left_minor > right_minor )) && return 0
(( left_minor < right_minor )) && return 1
(( left_patch > right_patch ))
}

if ! version_gt "$latest_version" "$current_version"; then
echo "No datadog-ci bump needed. Current default is $current_version; latest is $latest_version."
exit 0
fi

branch_name="${BRANCH_NAME:-datadog-ci-bump/${latest_version#v}}"

existing_pr_url=$(gh pr list \
--repo "$repo" \
--head "$branch_name" \
--state open \
--json url \
--jq '.[0].url // ""')
if [[ -n "$existing_pr_url" ]]; then
echo "An open bump PR already exists: $existing_pr_url"
exit 0
fi

if git show-ref --verify --quiet "refs/heads/$branch_name"; then
echo "Local branch '$branch_name' already exists. Delete it or set BRANCH_NAME to another value." >&2
exit 1
fi

git fetch "$remote" "$base_branch"
git checkout -b "$branch_name" FETCH_HEAD

scripts/bump-datadog-ci-version.sh "$latest_version"

git add action.yaml README.md
git commit -m "Bump datadog-ci to $latest_version"
git push -u "$remote" "$branch_name"

gh label create "$bump_label" \
--repo "$repo" \
--description "Triggers a junit-upload-github-action release after merge" \
--color "1D76DB" \
--force

body_file=$(mktemp)
trap 'rm -f "$body_file"' EXIT
cat > "$body_file" <<EOF
## Summary

Bumps the default \`datadog-ci-version\` from \`$current_version\` to \`$latest_version\`.

## Release behavior

Merging this PR with the \`$bump_label\` label will trigger the release workflow. That workflow creates the next immutable action tag, moves the major action tag, and creates a GitHub Release.
EOF

gh pr create \
--repo "$repo" \
--base "$base_branch" \
--head "$branch_name" \
--title "Bump datadog-ci to $latest_version" \
--body-file "$body_file" \
--label "$bump_label"
Loading
Loading