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
40 changes: 30 additions & 10 deletions actions/release/lang/js/publish/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,11 @@ runs:
- name: Install dependencies
shell: bash
working-directory: ${{ inputs.working_directory }}
run: pnpm install --frozen-lockfile
run: |
pnpm install --frozen-lockfile || {
echo "::error title=Dependency install failed::'pnpm install --frozen-lockfile' failed — the lockfile is likely out of sync with package.json (run 'pnpm install' and commit pnpm-lock.yaml)."
exit 1
}

- name: Build
if: ${{ inputs.build == 'true' }}
Expand Down Expand Up @@ -208,10 +212,12 @@ runs:
[ "$PROVENANCE" = "true" ] && ARGS+=(--provenance)
if [ "$DRY_RUN" = "true" ]; then
echo "DRY RUN: pnpm publish ${ARGS[*]} --dry-run"
pnpm publish "${ARGS[@]}" --dry-run
else
pnpm publish "${ARGS[@]}"
ARGS+=(--dry-run)
fi
pnpm publish "${ARGS[@]}" || {
echo "::error title=npm publish failed::auth/ENEEDAUTH → the npm trusted publisher must list this repo, workflow, and (if gated) environment; 'cannot publish over <version>' → the version already exists on npm (bump it)."
exit 1
}

- name: Create GitHub release
shell: bash
Expand Down Expand Up @@ -404,7 +410,7 @@ runs:
if echo "$RESPONSE" | jq -e '.ok' > /dev/null 2>&1; then
echo "Slack notification sent."
elif [ "$FAIL_ON_ERROR" = "true" ]; then
echo "Slack notification failed: $RESPONSE"
echo "::error title=Slack notification failed::$RESPONSE"
exit 1
else
echo "::warning::Slack notification failed: $RESPONSE"
Expand All @@ -420,10 +426,24 @@ runs:
npm --version
echo "=== pnpm ==="
pnpm --version || echo "(unavailable)"
echo "=== Registry ==="
pnpm config get registry
echo "=== package.json version ==="
node -p "require('./package.json').version" 2>/dev/null || echo "(unavailable)"
echo "=== package.json ==="
node -e '
const p = require("./package.json");
console.log(JSON.stringify({
name: p.name,
version: p.version,
private: p.private || false,
packageManager: p.packageManager,
engines: p.engines,
devEngines: p.devEngines,
publishConfig: p.publishConfig,
lifecycle: Object.fromEntries(
["prepublishOnly", "prepack", "prepare", "postpack"]
.filter((k) => p.scripts && p.scripts[k])
.map((k) => [k, p.scripts[k]]),
),
}, null, 2));
' 2>/dev/null || echo "(package.json unavailable)"

- name: Build failure message
if: ${{ failure() }}
Expand Down Expand Up @@ -479,7 +499,7 @@ runs:
if echo "$RESPONSE" | jq -e '.ok' > /dev/null 2>&1; then
echo "Slack notification sent."
elif [ "$FAIL_ON_ERROR" = "true" ]; then
echo "Slack notification failed: $RESPONSE"
echo "::error title=Slack notification failed::$RESPONSE"
exit 1
else
echo "::warning::Slack notification failed: $RESPONSE"
Expand Down
49 changes: 35 additions & 14 deletions actions/release/lang/js/validate/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,11 @@ runs:
- name: Install dependencies
shell: bash
working-directory: ${{ inputs.working_directory }}
run: pnpm install --frozen-lockfile
run: |
pnpm install --frozen-lockfile || {
echo "::error title=Dependency install failed::'pnpm install --frozen-lockfile' failed — the lockfile is likely out of sync with package.json (run 'pnpm install' and commit pnpm-lock.yaml)."
exit 1
}

- name: Read version
id: read-version
Expand All @@ -142,11 +146,15 @@ runs:
VERSION_OVERRIDE: ${{ inputs.version }}
run: |
if [ -n "$VERSION_OVERRIDE" ]; then
echo "version=$VERSION_OVERRIDE" >> $GITHUB_OUTPUT
VERSION="$VERSION_OVERRIDE"
else
VERSION=$(node -p "require('./package.json').version")
echo "version=$VERSION" >> $GITHUB_OUTPUT
fi
if [ -z "$VERSION" ] || [ "$VERSION" = "undefined" ]; then
echo "::error title=Could not read version::resolved an empty version — check the \"version\" field in package.json (or pass a version override)."
exit 1
fi
echo "version=$VERSION" >> $GITHUB_OUTPUT

- name: Check npm version availability
shell: bash
Expand All @@ -165,15 +173,14 @@ runs:
"$REGISTRY/$PACKAGE_NAME/$VERSION")
case "$CODE" in
200)
echo "Error: $PACKAGE_NAME@$VERSION already exists on npm — has the version been bumped?"
echo "::error title=Version already published::$PACKAGE_NAME@$VERSION already exists on npm — has the version been bumped?"
exit 1
;;
404)
echo "$PACKAGE_NAME@$VERSION is available on npm."
;;
*)
echo "Error: unexpected response from the npm registry (HTTP $CODE) checking $PACKAGE_NAME@$VERSION;"
echo "cannot confirm the version is unpublished — aborting rather than risk a bad release."
echo "::error title=Registry check failed::unexpected response from the npm registry (HTTP $CODE) checking $PACKAGE_NAME@$VERSION — cannot confirm the version is unpublished; aborting rather than risk a bad release."
exit 1
;;
esac
Expand All @@ -188,7 +195,7 @@ runs:
for c in "${OK[@]}"; do
[ "$(echo "$c" | xargs)" = "$CHANNEL" ] && exit 0
done
echo "Error: release channel '$CHANNEL' is not in the allowed set: $ALLOWED"
echo "::error title=Release channel not allowed::release channel '$CHANNEL' is not in the allowed set: $ALLOWED"
exit 1

- name: Validate SHA format
Expand All @@ -197,7 +204,7 @@ runs:
SHA: ${{ inputs.sha }}
run: |
if ! echo "$SHA" | grep -qE '^[0-9a-f]{40}$'; then
echo "Error: sha must be a full 40-character commit SHA — branch names and short SHAs are not accepted."
echo "::error title=Invalid release SHA::sha must be a full 40-character commit SHA — branch names and short SHAs are not accepted."
exit 1
fi

Expand All @@ -217,9 +224,9 @@ runs:

if git rev-parse "$TAG" >/dev/null 2>&1; then
if [ "$DRY_RUN" = "true" ]; then
echo "Warning: Tag $TAG already exists — skipping in dry run"
echo "::warning title=Release tag already exists::Tag $TAG already exists — skipping in dry run."
else
echo "Error: Tag $TAG already exists — has the version been bumped?"
echo "::error title=Release tag already exists::Tag $TAG already exists — has the version been bumped?"
exit 1
fi
fi
Expand Down Expand Up @@ -263,7 +270,21 @@ runs:
npm --version
echo "=== pnpm ==="
pnpm --version || echo "(unavailable)"
echo "=== Registry ==="
pnpm config get registry
echo "=== package.json version ==="
node -p "require('./package.json').version" 2>/dev/null || echo "(unavailable)"
echo "=== package.json ==="
node -e '
const p = require("./package.json");
console.log(JSON.stringify({
name: p.name,
version: p.version,
private: p.private || false,
packageManager: p.packageManager,
engines: p.engines,
devEngines: p.devEngines,
publishConfig: p.publishConfig,
lifecycle: Object.fromEntries(
["prepublishOnly", "prepack", "prepare", "postpack"]
.filter((k) => p.scripts && p.scripts[k])
.map((k) => [k, p.scripts[k]]),
),
}, null, 2));
' 2>/dev/null || echo "(package.json unavailable)"
25 changes: 20 additions & 5 deletions actions/release/lang/py/publish/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,10 @@ runs:
else
ARGS+=(--no-attestations)
fi
uv publish "${ARGS[@]}"
uv publish "${ARGS[@]}" || {
echo "::error title=PyPI publish failed::auth/OIDC error → the PyPI trusted publisher must list this repo, workflow, and (if gated) environment; a 400 'File already exists' → the version is already on PyPI (bump it)."
exit 1
}

- name: Create GitHub release
shell: bash
Expand Down Expand Up @@ -372,7 +375,7 @@ runs:
if echo "$RESPONSE" | jq -e '.ok' > /dev/null 2>&1; then
echo "Slack notification sent."
elif [ "$FAIL_ON_ERROR" = "true" ]; then
echo "Slack notification failed: $RESPONSE"
echo "::error title=Slack notification failed::$RESPONSE"
exit 1
else
echo "::warning::Slack notification failed: $RESPONSE"
Expand All @@ -390,8 +393,20 @@ runs:
echo "${UV_PYTHON:-(unset)}"
echo "=== Built artifacts ==="
ls -la dist 2>/dev/null || echo "(no dist/)"
echo "=== pyproject.toml ==="
head -40 pyproject.toml 2>/dev/null || echo "(no pyproject.toml)"
echo "=== pyproject.toml (release-relevant) ==="
uv run --no-project python -c '
import json, tomllib, pathlib
t = tomllib.loads(pathlib.Path("pyproject.toml").read_text())
proj = t.get("project", {})
print(json.dumps({
"name": proj.get("name"),
"version": proj.get("version") or ("(dynamic)" if "version" in proj.get("dynamic", []) else None),
"requires-python": proj.get("requires-python"),
"dependencies": proj.get("dependencies"),
"optional-dependencies": sorted((proj.get("optional-dependencies") or {}).keys()),
"build-system": t.get("build-system"),
}, indent=2))
' 2>/dev/null || echo "(pyproject.toml unavailable)"

- name: Build failure message
if: ${{ failure() }}
Expand Down Expand Up @@ -447,7 +462,7 @@ runs:
if echo "$RESPONSE" | jq -e '.ok' > /dev/null 2>&1; then
echo "Slack notification sent."
elif [ "$FAIL_ON_ERROR" = "true" ]; then
echo "Slack notification failed: $RESPONSE"
echo "::error title=Slack notification failed::$RESPONSE"
exit 1
else
echo "::warning::Slack notification failed: $RESPONSE"
Expand Down
35 changes: 25 additions & 10 deletions actions/release/lang/py/validate/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -112,13 +112,17 @@ runs:
VERSION_FILE: ${{ inputs.version_file }}
run: |
if [ -n "$VERSION_OVERRIDE" ]; then
echo "version=$VERSION_OVERRIDE" >> "$GITHUB_OUTPUT"
VERSION="$VERSION_OVERRIDE"
else
# exec the version file in an isolated namespace (no package import needed),
# matching how the SDKs expose VERSION in a standalone version.py.
VERSION=$(uv run --no-project python -c "import runpy,sys; print(runpy.run_path(sys.argv[1])['VERSION'])" "$VERSION_FILE")
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
fi
if [ -z "$VERSION" ] || [ "$VERSION" = "None" ]; then
echo "::error title=Could not read version::resolved an empty version — check VERSION in $VERSION_FILE (or pass a version override)."
exit 1
fi
echo "version=$VERSION" >> "$GITHUB_OUTPUT"

- name: Check PyPI version availability
shell: bash
Expand All @@ -135,15 +139,14 @@ runs:
"https://pypi.org/pypi/$PACKAGE_NAME/$VERSION/json")
case "$CODE" in
200)
echo "Error: $PACKAGE_NAME $VERSION already exists on PyPI — has the version been bumped?"
echo "::error title=Version already published::$PACKAGE_NAME $VERSION already exists on PyPI — has the version been bumped?"
exit 1
;;
404)
echo "$PACKAGE_NAME $VERSION is available on PyPI."
;;
*)
echo "Error: unexpected response from PyPI (HTTP $CODE) checking $PACKAGE_NAME $VERSION;"
echo "cannot confirm the version is unpublished — aborting rather than risk a bad release."
echo "::error title=Registry check failed::unexpected response from PyPI (HTTP $CODE) checking $PACKAGE_NAME $VERSION — cannot confirm the version is unpublished; aborting rather than risk a bad release."
exit 1
;;
esac
Expand All @@ -154,7 +157,7 @@ runs:
SHA: ${{ inputs.sha }}
run: |
if ! echo "$SHA" | grep -qE '^[0-9a-f]{40}$'; then
echo "Error: sha must be a full 40-character commit SHA — branch names and short SHAs are not accepted."
echo "::error title=Invalid release SHA::sha must be a full 40-character commit SHA — branch names and short SHAs are not accepted."
exit 1
fi

Expand All @@ -174,9 +177,9 @@ runs:

if git rev-parse "$TAG" >/dev/null 2>&1; then
if [ "$DRY_RUN" = "true" ]; then
echo "Warning: Tag $TAG already exists — skipping in dry run"
echo "::warning title=Release tag already exists::Tag $TAG already exists — skipping in dry run."
else
echo "Error: Tag $TAG already exists — has the version been bumped?"
echo "::error title=Release tag already exists::Tag $TAG already exists — has the version been bumped?"
exit 1
fi
fi
Expand Down Expand Up @@ -228,5 +231,17 @@ runs:
echo "${UV_PYTHON:-(unset)}"
echo "=== Built artifacts ==="
ls -la dist 2>/dev/null || echo "(no dist/)"
echo "=== pyproject.toml ==="
head -40 pyproject.toml 2>/dev/null || echo "(no pyproject.toml)"
echo "=== pyproject.toml (release-relevant) ==="
uv run --no-project python -c '
import json, tomllib, pathlib
t = tomllib.loads(pathlib.Path("pyproject.toml").read_text())
proj = t.get("project", {})
print(json.dumps({
"name": proj.get("name"),
"version": proj.get("version") or ("(dynamic)" if "version" in proj.get("dynamic", []) else None),
"requires-python": proj.get("requires-python"),
"dependencies": proj.get("dependencies"),
"optional-dependencies": sorted((proj.get("optional-dependencies") or {}).keys()),
"build-system": t.get("build-system"),
}, indent=2))
' 2>/dev/null || echo "(pyproject.toml unavailable)"
4 changes: 2 additions & 2 deletions actions/release/lang/ruby/publish/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ runs:
if echo "$RESPONSE" | jq -e '.ok' > /dev/null 2>&1; then
echo "Slack notification sent."
elif [ "$FAIL_ON_ERROR" = "true" ]; then
echo "Slack notification failed: $RESPONSE"
echo "::error title=Slack notification failed::$RESPONSE"
exit 1
else
echo "::warning::Slack notification failed: $RESPONSE"
Expand Down Expand Up @@ -378,7 +378,7 @@ runs:
if echo "$RESPONSE" | jq -e '.ok' > /dev/null 2>&1; then
echo "Slack notification sent."
elif [ "$FAIL_ON_ERROR" = "true" ]; then
echo "Slack notification failed: $RESPONSE"
echo "::error title=Slack notification failed::$RESPONSE"
exit 1
else
echo "::warning::Slack notification failed: $RESPONSE"
Expand Down
19 changes: 11 additions & 8 deletions actions/release/lang/ruby/validate/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,15 @@ runs:
VERSION_MODULE: ${{ inputs.version_module }}
run: |
if [ -n "$VERSION_OVERRIDE" ]; then
echo "version=$VERSION_OVERRIDE" >> $GITHUB_OUTPUT
VERSION="$VERSION_OVERRIDE"
else
VERSION=$(ruby -r "./$VERSION_FILE" -e "puts Object.const_get(ENV.fetch('VERSION_MODULE')).const_get(:VERSION)")
echo "version=$VERSION" >> $GITHUB_OUTPUT
fi
if [ -z "$VERSION" ]; then
echo "::error title=Could not read version::resolved an empty version — check VERSION in $VERSION_FILE (module $VERSION_MODULE), or pass a version override."
exit 1
fi
echo "version=$VERSION" >> $GITHUB_OUTPUT

- name: Check RubyGems version availability
shell: bash
Expand All @@ -105,15 +109,14 @@ runs:
"https://rubygems.org/api/v2/rubygems/$PACKAGE_NAME/versions/$VERSION.json")
case "$CODE" in
200)
echo "Error: $PACKAGE_NAME $VERSION already exists on RubyGems — has the version been bumped?"
echo "::error title=Version already published::$PACKAGE_NAME $VERSION already exists on RubyGems — has the version been bumped?"
exit 1
;;
404)
echo "$PACKAGE_NAME $VERSION is available on RubyGems."
;;
*)
echo "Error: unexpected response from RubyGems (HTTP $CODE) checking $PACKAGE_NAME $VERSION;"
echo "cannot confirm the version is unpublished — aborting rather than risk a bad release."
echo "::error title=Registry check failed::unexpected response from RubyGems (HTTP $CODE) checking $PACKAGE_NAME $VERSION — cannot confirm the version is unpublished; aborting rather than risk a bad release."
exit 1
;;
esac
Expand All @@ -124,7 +127,7 @@ runs:
SHA: ${{ inputs.sha }}
run: |
if ! echo "$SHA" | grep -qE '^[0-9a-f]{40}$'; then
echo "Error: sha must be a full 40-character commit SHA — branch names and short SHAs are not accepted."
echo "::error title=Invalid release SHA::sha must be a full 40-character commit SHA — branch names and short SHAs are not accepted."
exit 1
fi

Expand All @@ -144,9 +147,9 @@ runs:

if git rev-parse "$TAG" >/dev/null 2>&1; then
if [ "$DRY_RUN" = "true" ]; then
echo "Warning: Tag $TAG already exists — skipping in dry run"
echo "::warning title=Release tag already exists::Tag $TAG already exists — skipping in dry run."
else
echo "Error: Tag $TAG already exists — has the version been bumped?"
echo "::error title=Release tag already exists::Tag $TAG already exists — has the version been bumped?"
exit 1
fi
fi
Expand Down
2 changes: 1 addition & 1 deletion actions/release/notify-pending/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ runs:
if echo "$RESPONSE" | jq -e '.ok' > /dev/null 2>&1; then
echo "Slack notification sent."
elif [ "$FAIL_ON_ERROR" = "true" ]; then
echo "Slack notification failed: $RESPONSE"
echo "::error title=Slack notification failed::$RESPONSE"
exit 1
else
echo "::warning::Slack notification failed: $RESPONSE"
Expand Down
Loading