Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
bcb6367
Add `init-package.sh` script
Drarig29 Jan 15, 2026
3a0e179
Adapt `migrate.sh` script
Drarig29 Jan 15, 2026
af0ad1d
Fix lint-packages script
Drarig29 Jan 15, 2026
ef19812
Add docs about listing packages
Drarig29 Jan 15, 2026
0f96c7e
Check published packages in CI
Drarig29 Jan 15, 2026
59955fe
Init `junit` plugin
Drarig29 Jan 15, 2026
1b58d6f
Colorize scripts
Drarig29 Jan 15, 2026
b5b1f58
Reintroduce `--provenance`
Drarig29 Jan 15, 2026
0d10074
Publish junit `0.0.3` with `--provenance`
Drarig29 Jan 15, 2026
4880c9c
Delete temporary workflow
Drarig29 Jan 15, 2026
d91da28
Run migrate script
Drarig29 Jan 15, 2026
f77411e
Split `JunitUploadCommand`
Drarig29 Jan 15, 2026
67e4e19
Run `yarn lint:packages --fix`
Drarig29 Jan 15, 2026
918c36f
Fix tests
Drarig29 Jan 15, 2026
d02698b
Run `yarn lint:packages --fix` again
Drarig29 Jan 15, 2026
ea53ee5
Change version at the end of init script
Drarig29 Jan 15, 2026
aefdd28
Fail CI on PRs with empty initialized packages
Drarig29 Jan 15, 2026
cb9e936
Merge branch 'corentin.girard/SYNTH-21709/migrate-junit' into corenti…
Drarig29 Jan 15, 2026
251d8d4
Rename `init-package.sh` to `create-package.sh`
Drarig29 Jan 19, 2026
9c59805
Add `package:create` and `package:migrate` aliases
Drarig29 Jan 19, 2026
4b54a3a
Reduce the role of `create-package.sh`
Drarig29 Jan 19, 2026
b3158ff
Make new script to check NPM packages
Drarig29 Jan 19, 2026
c2adc0d
Merge branch 'master' into corentin.girard/SYNTH-23939/init-plugin
Drarig29 Jan 19, 2026
1dfd4e4
Undo ci.yml changes
Drarig29 Jan 19, 2026
ada3efa
Change publish-release.yml instead
Drarig29 Jan 19, 2026
7ad9a71
Stricter regex for tag
Drarig29 Jan 19, 2026
1256623
Still run `yarn install` in create package script
Drarig29 Jan 19, 2026
573c719
Rename scripts
Drarig29 Jan 19, 2026
48d387f
Update naming
Drarig29 Jan 19, 2026
af78369
Extract PR author and ping them
Drarig29 Jan 19, 2026
55cc372
Remove temporary fail safe
Drarig29 Jan 19, 2026
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: 24 additions & 5 deletions .github/workflows/publish-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,34 @@ name: Publish package on NPM
on:
push:
tags:
- v* # Any version tag
- 'v[0-9]+.[0-9]+.[0-9]+'

permissions:
id-token: write # To publish on NPM with provenance and to federate tokens
id-token: write # For OIDC publishing with provenance and to federate tokens
contents: write # Required for the draft release

jobs:
pre-release-checks:
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Install node
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: 22.19.0
- name: Install project dependencies
run: yarn install --immutable --mode=skip-build
- name: Check NPM packages
run: yarn check-npm-packages
env:
# Used to post comments on the PR
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Comment on lines +25 to +29
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Example comment: #2061 (comment)

Image


create-draft-release:
runs-on: ubuntu-latest
needs: pre-release-checks
outputs:
release-id: ${{ steps.draft-release.outputs.result }}
steps:
Expand Down Expand Up @@ -258,11 +277,11 @@ jobs:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: 24.11.1 # Version supporting OIDC
registry-url: "https://registry.npmjs.org"
node-version: '24' # Needed for OIDC publishing
registry-url: 'https://registry.npmjs.org'
Comment on lines +280 to +281
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

- run: yarn install --immutable
- run: yarn build
- run: yarn publish:all
- run: yarn publish:all --provenance
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reintroduced --provenance to get back the checkmark on NPM:

Image


bump-ci-integrations:
name: Bump datadog-ci in integration
Expand Down
20 changes: 20 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,26 @@
Pull requests for bug fixes are welcome, but before submitting new features or changes to current functionality, [open an issue](https://github.com/DataDog/datadog-ci/issues/new)
and discuss your ideas or propose the changes you wish to make. After a resolution is reached, a PR can be submitted for review.

### Listing NPM packages

This repository is a monorepo containing multiple packages published to NPM. You can list all packages with the following command:

```sh
npm search 'maintainer:datadog keywords:datadog-ci'
```

To only list the plugins:

```sh
npm search 'maintainer:datadog keywords:datadog-ci,plugin'
```

You can also use the following datadog-ci command to get more information:

```sh
yarn launch plugin list --all
```

### Running command in development environment

When developing the tool, it is possible to run commands using `yarn launch`. It relies on `tsx`, so it does not require building the project for every new change.
Expand Down
183 changes: 183 additions & 0 deletions bin/check-npm-packages.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
#!/bin/bash

set -euo pipefail

# This script checks if all local packages are published to NPM.
# It can also first-time publish missing packages when run with --fix.
#
# Usage:
# ./bin/check-npm-packages.sh # Check mode (default) - exits 1 if packages are missing
# ./bin/check-npm-packages.sh --fix # Fix mode - publishes missing packages
# ./bin/check-npm-packages.sh --fix --dry-run # Fix mode with dry-run - simulates publishing

MODE="check"
DRY_RUN=false

while [[ $# -gt 0 ]]; do
case $1 in
--fix)
MODE="fix"
shift
;;
--dry-run)
DRY_RUN=true
shift
;;
-*)
echo "Unknown option: $1"
echo "Usage: $0 [--fix] [--dry-run]"
exit 1
;;
*)
echo "Unknown argument: $1"
echo "Usage: $0 [--fix] [--dry-run]"
exit 1
;;
esac
done

if [ "$DRY_RUN" = true ] && [ "$MODE" != "fix" ]; then
echo "Error: --dry-run can only be used with --fix"
exit 1
fi

# Colors
BOLD='\033[1m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
RED='\033[0;31m'
NC='\033[0m'

echo -e "${BOLD}Checking for unpublished packages...${NC}"
echo

# Get local and remote packages
local_packages=$(yarn workspaces list --json --no-private | jq -r '.name' | sort)
remote_packages=$(npm search 'maintainer:datadog keywords:datadog-ci' --json | jq -r '.[].name' | sort)

# Find packages that exist locally but not on NPM
missing_packages=()
while IFS= read -r pkg; do
if [ -n "$pkg" ] && ! echo "$remote_packages" | grep -q "^${pkg}$"; then
missing_packages+=("$pkg")
fi
done <<< "$local_packages"

# Exit early if everything is good
if [ ${#missing_packages[@]} -eq 0 ]; then
echo -e "${GREEN}All local packages exist on NPM ✅${NC}"
exit 0
fi

# Otherwise, report missing packages
echo -e "${RED}The following packages are not published to NPM yet:${NC}"
for pkg in "${missing_packages[@]}"; do
echo " - $pkg"
done

# In CI environment, post a comment on the PR
if [ -n "${GITHUB_TOKEN:-}" ] && [ -n "${GITHUB_REPOSITORY:-}" ] && [ -n "${GITHUB_SHA:-}" ]; then
# Get the PR number and author associated with this commit
PR_RESPONSE=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
"https://api.github.com/repos/$GITHUB_REPOSITORY/commits/$GITHUB_SHA/pulls")

PR_NUMBER=$(echo "$PR_RESPONSE" | jq -r '.[0].number // empty')
PR_AUTHOR=$(echo "$PR_RESPONSE" | jq -r '.[0].user.login // empty')

DIFF_OUTPUT=$(diff -u --label "Published packages (Actual)" --label "Local packages (Expected)" \
<(echo "$remote_packages") <(echo "$local_packages")) || true

COMMENT_BODY="### Some packages were not first-time published to NPM yet ❌

\`\`\`diff
$DIFF_OUTPUT
\`\`\`

Hi @$PR_AUTHOR, please **ask an admin** to follow the instructions at https://datadoghq.atlassian.net/wiki/x/QYDRaQE"

if [ -n "$PR_NUMBER" ]; then
# Post comment on the PR
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/$GITHUB_REPOSITORY/issues/$PR_NUMBER/comments" \
-d "$(jq -n --arg body "$COMMENT_BODY" '{body: $body}')" > /dev/null

echo -e "${BLUE}Posted comment on PR #$PR_NUMBER (author: @$PR_AUTHOR)${NC}"
else
# Fallback when PR is not found
echo -e "${RED}No PR found for commit $GITHUB_SHA${NC}"
echo -e "${BLUE}This would be the comment body:${NC}"
echo "$COMMENT_BODY"
fi
fi

# Do not continue if we are in check mode
if [ "$MODE" = "check" ]; then
echo
echo -e "${BOLD}Run with --fix to publish these packages${NC}"
echo -e "See instructions at ${BLUE}https://datadoghq.atlassian.net/wiki/x/QYDRaQE${NC}"
exit 1
fi

# Fix mode - publish missing packages
echo
echo -e "${BOLD}Publishing missing packages to NPM...${NC}"
echo
echo -e "${BOLD}Please read the instructions${NC} at ${BLUE}https://datadoghq.atlassian.net/wiki/x/QYDRaQE${NC} before proceeding."
echo

if [ "$DRY_RUN" = true ]; then
echo -e "${BOLD}[DRY-RUN]${NC} None of the packages will actually be published."
echo
fi

read -rsp "Enter your NPM auth token: " INIT_NPM_AUTH_TOKEN
echo
if [ -z "$INIT_NPM_AUTH_TOKEN" ]; then
echo "Error: NPM auth token cannot be empty"
exit 1
fi

# Export this for subsequent yarn commands in the script
export INIT_NPM_AUTH_TOKEN

# Do not hardcode the token in .yarnrc.yml, it will be read from the environment variable
yarn config set npmAuthToken '${INIT_NPM_AUTH_TOKEN}'
echo

for pkg in "${missing_packages[@]}"; do
echo -e "${BLUE}Publishing ${BOLD}$pkg${NC}${BLUE}...${NC}"

# Get the package directory
pkg_dir=$(yarn workspaces list --json | jq -r "select(.name == \"$pkg\") | .location")
pkg_json="$pkg_dir/package.json"

# Save original version
original_version=$(jq -r .version "$pkg_json")

# Set version to 0.0.1 for first-time publish
jq '.version = "0.0.1"' "$pkg_json" | sponge "$pkg_json"

if [ "$DRY_RUN" = true ]; then
echo " [DRY-RUN] Would publish $pkg@0.0.1"
yarn workspace "$pkg" npm publish --dry-run 2>&1 | sed 's/^/ /'
else
yarn workspace "$pkg" npm publish 2>&1 | sed 's/^/ /'
echo -e " ${GREEN}Successfully published $pkg@0.0.1${NC}"
fi

# Restore original version
jq --arg version "$original_version" '.version = $version' "$pkg_json" | sponge "$pkg_json"
echo
done

echo -e "${BOLD}Cleaning up...${NC}"
yarn config unset npmAuthToken

echo
if [ "$DRY_RUN" = true ]; then
echo -e "${GREEN}[DRY-RUN] Would have published ${#missing_packages[@]} package(s)${NC}"
else
echo -e "${GREEN}Successfully published ${#missing_packages[@]} package(s)${NC}"
fi
96 changes: 96 additions & 0 deletions bin/create-plugin.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#!/bin/bash

set -euo pipefail

SCOPE=""

while [[ $# -gt 0 ]]; do
case $1 in
-*)
echo "Unknown option: $1"
echo "Usage: $0 <scope>"
exit 1
;;
*)
SCOPE="$1"
shift
;;
esac
done

if [ -z "$SCOPE" ]; then
echo "Usage: $0 <scope>"
exit 1
fi
PLUGIN_PKG="@datadog/datadog-ci-plugin-$SCOPE"
PLUGIN_DIR="packages/plugin-$SCOPE"

if [ -d "$PLUGIN_DIR" ]; then
echo "Plugin directory $PLUGIN_DIR already exists!"
echo "This script should only be run once per scope, before migrate.sh"
exit 1
fi

BOLD='\033[1m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

echo -e "This script will initialize an empty package for ${BLUE}${BOLD}$PLUGIN_PKG${NC}"
echo

echo -e "${BOLD}1. Creating plugin directory structure${NC}"
mkdir -p "$PLUGIN_DIR"
env cp LICENSE "$PLUGIN_DIR"
echo "Empty package" > "$PLUGIN_DIR/README.md"
cat > "$PLUGIN_DIR/package.json" <<EOF
{
"name": "$PLUGIN_PKG",
"version": "$(jq -r .version packages/base/package.json)",
"description": "Datadog CI plugin for \`$SCOPE\` commands",
"license": "Apache-2.0",
"keywords": [
"datadog",
"datadog-ci",
"plugin"
],
"homepage": "https://github.com/DataDog/datadog-ci/tree/master/$PLUGIN_DIR",
"repository": {
"type": "git",
"url": "https://github.com/DataDog/datadog-ci.git",
"directory": "$PLUGIN_DIR"
},
"exports": {
"./package.json": "./package.json",
"./commands/*": {
"development": "./src/commands/*.ts",
"default": "./dist/commands/*.js"
}
},
"files": [
"dist/**/*",
"README",
"LICENSE"
],
"publishConfig": {
"access": "public"
},
"scripts": {
"build": "yarn package:clean; yarn package:build",
"lint": "yarn package:lint",
"prepack": "yarn package:clean-dist"
},
"peerDependencies": {
"@datadog/datadog-ci-base": "workspace:*"
}
}
EOF

echo -e "${BOLD}2. Running yarn install${NC}"
yarn install 2>&1 | sed 's/^/ /'

echo
echo -e "${GREEN}Package created successfully${NC}"

echo
echo -e "${BLUE}If needed, you can now run: ${BOLD}bin/migrate.sh $SCOPE${NC}"
Loading