Skip to content

Release

Release #20

Workflow file for this run

name: Release
# Release only after CI succeeds on main and the tested commit has a vX.Y.Z tag.
# `docks release` pushes main + tag together; CI runs on main, then this workflow
# runs via workflow_run (not on tag push — that raced CI and produced false failures).
# If CI fails, cleanup-orphan-tag removes semver tags on that commit that never
# received a GitHub Release, so release history stays contiguous.
on:
workflow_run:
workflows: [CI]
types: [completed]
permissions:
actions: read
contents: write
id-token: write
jobs:
resolve:
if: >
github.event.workflow_run.conclusion == 'success' &&
github.event.workflow_run.event == 'push' &&
github.event.workflow_run.head_branch == 'main'
runs-on: ubuntu-latest
outputs:
version: ${{ steps.tag.outputs.version }}
steps:
- name: Checkout tested commit
uses: actions/checkout@v7
with:
ref: ${{ github.event.workflow_run.head_sha }}
fetch-depth: 0
- name: Find release tag on commit
id: tag
run: |
SHA="${{ github.event.workflow_run.head_sha }}"
VERSION=$(git tag --points-at HEAD | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | head -1 || true)
if [ -z "$VERSION" ]; then
echo "No release tag on $SHA; skipping release."
echo "version=" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "CI success: release tag $VERSION on $SHA"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
cleanup-orphan-tag:
if: >
github.event.workflow_run.conclusion == 'failure' &&
github.event.workflow_run.event == 'push' &&
github.event.workflow_run.head_branch == 'main'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout tested commit
uses: actions/checkout@v7
with:
ref: ${{ github.event.workflow_run.head_sha }}
fetch-depth: 0
- name: Delete unreleased semver tags from failed CI
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SHA: ${{ github.event.workflow_run.head_sha }}
run: |
git fetch --tags origin
mapfile -t TAGS < <(git tag --points-at "$SHA" | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' || true)
if [ ${#TAGS[@]} -eq 0 ]; then
echo "No semver tags on $SHA"
exit 0
fi
for TAG in "${TAGS[@]}"; do
if gh release view "$TAG" >/dev/null 2>&1; then
echo "GitHub Release exists for $TAG; keeping tag"
continue
fi
echo "Deleting orphan tag $TAG (CI failed before release)"
git push origin ":refs/tags/$TAG"
done
release:
needs: resolve
if: needs.resolve.outputs.version != ''
permissions:
contents: write
uses: ./.github/workflows/app-release.yml
with:
version: ${{ needs.resolve.outputs.version }}
publish_dir: packages/app/dist
build_command: npm run build:app
node_version_file: .nvmrc
cname: docks.eclipse.dev
secrets: inherit
deploy-docs:
needs: release
if: needs.release.outputs.version != ''
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout code
uses: actions/checkout@v7
with:
ref: ${{ needs.release.outputs.version }}
- name: Set up Node.js
uses: actions/setup-node@v7
with:
node-version-file: '.nvmrc'
cache: npm
- name: Install dependencies
run: npm ci
- name: Build docs
env:
DOCKS_DOCS_VERSION: ${{ needs.release.outputs.version }}
run: npm run docs:build
- name: Deploy docs to GitHub Pages
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: docs/.vitepress/dist
destination_dir: docs
publish_branch: gh-pages
keep_files: true
- name: Docs deployment summary
run: |
echo "## Docs Deployment Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "- **Release**: ${{ needs.release.outputs.version }}" >> $GITHUB_STEP_SUMMARY
echo "- **Branch**: gh-pages" >> $GITHUB_STEP_SUMMARY
echo "- **Path**: /docs/" >> $GITHUB_STEP_SUMMARY
echo "- **URL**: https://docks.eclipse.dev/docs/" >> $GITHUB_STEP_SUMMARY
echo "- **Commit**: ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY
publish-npm:
needs: release
if: needs.release.outputs.version != ''
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- name: Checkout code
uses: actions/checkout@v7
with:
ref: ${{ needs.release.outputs.version }}
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v7
with:
node-version-file: '.nvmrc'
registry-url: "https://registry.npmjs.org"
cache: npm
- name: Install dependencies
run: npm ci
- name: Update package versions (CI only, not committed)
run: |
VERSION="${{ needs.release.outputs.version }}"
VERSION="${VERSION#v}"
for pkg in packages/core packages/extension-* packages/create-app packages/cli; do
[ -d "$pkg" ] && (cd "$pkg" && npm version "$VERSION" --no-git-tag-version) && echo "Updated $pkg to $VERSION"
done
- name: Build core package
run: npm run build
- name: Build extension packages
run: npm run build:extensions
- name: Run type check
run: npm run type-check
continue-on-error: true
- name: Publish core, extensions, create-app, and cli to npm
run: |
for pkg in packages/core packages/extension-* packages/create-app packages/cli; do
if [ -d "$pkg" ]; then
if grep -q '"private":\s*true' "$pkg/package.json" 2>/dev/null; then
echo "Skipping $pkg (private)"
else
echo "Publishing $pkg..."
(cd "$pkg" && npm publish --access public --provenance)
fi
fi
done