Skip to content
Open
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
43 changes: 43 additions & 0 deletions .github/scripts/cleanup-p2-snapshots.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/usr/bin/env bash
# Removes old p2 snapshots from gh-pages, keeping the last 20.
# Ordering uses the .created timestamp written by publish-p2-ghpages.sh;
# dirs without that file (pre-dating this change) are treated as oldest.
# Required env vars: GITHUB_TOKEN

set -euo pipefail

KEEP=20

cd gh-pages
git config user.email "github-actions[bot]@users.noreply.github.com"
git config user.name "github-actions[bot]"

if [ -d p2/snapshots ]; then
to_delete=$(
for d in $(ls -1 p2/snapshots | grep -v latest); do
ts=0
[ -f "p2/snapshots/$d/.created" ] && ts=$(cat "p2/snapshots/$d/.created")
printf '%s %s\n' "$ts" "$d"
done | sort -n | head -n -"$KEEP" | awk '{print $2}'
)
if [ -n "$to_delete" ]; then
echo "$to_delete" | xargs -I{} rm -rf "p2/snapshots/{}"
fi
fi

git add -A
if git diff --cached --quiet; then
echo "No snapshot cleanup needed"
exit 0
fi
git commit -m "Clean up old p2 snapshots"
for attempt in 1 2 3; do
if git push origin HEAD:gh-pages; then
exit 0
fi
echo "Push attempt $attempt failed; fetching and rebasing"
git fetch origin gh-pages
git rebase origin/gh-pages
done
echo "Failed to push gh-pages after 3 attempts"
exit 1
127 changes: 127 additions & 0 deletions .github/scripts/publish-p2-ghpages.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
#!/usr/bin/env bash
# Publishes the p2 update site to the gh-pages branch.
#
# Snapshot mode (RELEASE_VERSION unset):
# Copies ddk-repository/target/repository/ → p2/snapshots/<sha8>/
# Updates p2/snapshots/latest/ composite repository
#
# Release mode (RELEASE_VERSION set):
# Copies p2/snapshots/<SNAPSHOT_SHA>/ → p2/releases/<RELEASE_VERSION>/
# Updates p2/releases/latest/ composite repository
#
# Required env vars: GITHUB_TOKEN, GITHUB_SHA, GITHUB_REPOSITORY
# Release-only vars: RELEASE_VERSION, SNAPSHOT_SHA

set -euo pipefail

write_composite() {
local dir="$1"
local name="$2"
local child="$3"
rm -rf "$dir"
mkdir -p "$dir"
cat > "$dir/p2.index" << 'EOF'
version=1
metadata.repository.factory.order=compositeContent.xml,\!
artifact.repository.factory.order=compositeArtifacts.xml,\!
EOF
cat > "$dir/compositeContent.xml" << EOF
<?xml version='1.0' encoding='UTF-8'?>
<?compositeMetadataRepository version='1.0.0'?>
<repository name='$name' type='org.eclipse.equinox.internal.p2.metadata.repository.CompositeMetadataRepository' version='1.0.0'>
<properties size='1'><property name='p2.timestamp' value='$TIMESTAMP'/></properties>
<children size='1'><child location='$child'/></children>
</repository>
EOF
cat > "$dir/compositeArtifacts.xml" << EOF
<?xml version='1.0' encoding='UTF-8'?>
<?compositeArtifactRepository version='1.0.0'?>
<repository name='$name' type='org.eclipse.equinox.internal.p2.artifact.repository.CompositeArtifactRepository' version='1.0.0'>
<properties size='1'><property name='p2.timestamp' value='$TIMESTAMP'/></properties>
<children size='1'><child location='$child'/></children>
</repository>
EOF
}

cd gh-pages
git config user.email "github-actions[bot]@users.noreply.github.com"
git config user.name "github-actions[bot]"

touch .nojekyll

if [ -n "${RELEASE_VERSION:-}" ]; then
TARGET="p2/releases/$RELEASE_VERSION"
REF_DESC="release $RELEASE_VERSION"
rm -rf "$TARGET"
mkdir -p "$TARGET"
cp -r "p2/snapshots/$SNAPSHOT_SHA/." "$TARGET/"
else
TARGET="p2/snapshots/${GITHUB_SHA::8}"
REF_DESC="snapshot ${GITHUB_SHA::8}"
rm -rf "$TARGET"
mkdir -p "$TARGET"
cp -r ../ddk-repository/target/repository/. "$TARGET/"
date +%s > "$TARGET/.created"
fi

TIMESTAMP="$(date +%s)000"
if [ -n "${RELEASE_VERSION:-}" ]; then
HIGHEST=$(ls -1 p2/releases | grep -v latest | sort -Vr | head -1)
write_composite p2/releases/latest "DDK p2 Latest Release" "../$HIGHEST/"
else
SHORT_SHA="${GITHUB_SHA::8}"
write_composite p2/snapshots/latest "DDK p2 Latest Snapshot" "../$SHORT_SHA/"
fi

# Generate index.html
{
echo '<!DOCTYPE html>'
echo '<html><body>'
echo '<h1>DSL DevKit p2 Repository</h1>'
echo '<h2>Snapshots</h2>'
echo '<ul>'
if [ -d p2/snapshots/latest ]; then
echo ' <li><a href="p2/snapshots/latest/">Latest Snapshot</a></li>'
fi
if [ -d p2/snapshots ]; then
while IFS= read -r s; do
echo " <li><a href=\"p2/snapshots/$s/\">$s</a></li>"
done < <(
for d in $(ls -1 p2/snapshots | grep -v latest); do
ts=0
[ -f "p2/snapshots/$d/.created" ] && ts=$(cat "p2/snapshots/$d/.created")
printf '%s %s\n' "$ts" "$d"
done | sort -rn | head -20 | awk '{print $2}'
)
fi
echo '</ul>'
if [ -d p2/releases ] && [ -n "$(ls -A p2/releases 2>/dev/null)" ]; then
echo '<h2>Releases</h2>'
echo '<ul>'
if [ -d p2/releases/latest ]; then
echo ' <li><a href="p2/releases/latest/">Latest Release</a></li>'
fi
for v in $(ls -1 p2/releases | grep -v latest | sort -Vr); do
echo " <li><a href=\"p2/releases/$v/\">$v</a></li>"
done
echo '</ul>'
fi
echo '</body></html>'
} > index.html

git add -A
if git diff --cached --quiet; then
echo "No changes to publish"
exit 0
fi
git commit -m "Publish $REF_DESC"
for attempt in 1 2 3; do
if git push origin HEAD:gh-pages; then
exit 0
fi
echo "Push attempt $attempt failed; fetching and rebasing"
git fetch origin gh-pages
git rebase origin/gh-pages
done
echo "Failed to push gh-pages after 3 attempts"
exit 1
156 changes: 156 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
name: release

on:
workflow_dispatch:
inputs:
branch:
description: 'Branch to release from'
required: false
default: master
type: string
version_bump:
description: 'Version component to bump'
required: false
default: patch
type: choice
options:
- patch
- minor
- major

concurrency:
group: publish-ghpages-${{ github.repository }}
cancel-in-progress: false

permissions:
contents: write

jobs:
create_tag:
runs-on: ubuntu-24.04
environment: release
outputs:
tag: ${{ steps.version.outputs.tag }}
snapshot_sha: ${{ steps.snapshot.outputs.sha }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
ref: ${{ inputs.branch }}
fetch-depth: 0

- name: Compute next version
id: version
run: |
LATEST=$(git tag --list 'v*' --sort=-version:refname | head -1)
if [ -z "$LATEST" ]; then
LATEST="v0.0.0"
fi
VERSION="${LATEST#v}"
MAJOR=$(echo "$VERSION" | cut -d. -f1)
MINOR=$(echo "$VERSION" | cut -d. -f2)
PATCH=$(echo "$VERSION" | cut -d. -f3)
case "${{ inputs.version_bump }}" in
major) MAJOR=$((MAJOR+1)); MINOR=0; PATCH=0 ;;
minor) MINOR=$((MINOR+1)); PATCH=0 ;;
patch) PATCH=$((PATCH+1)) ;;
esac
NEW_TAG="v${MAJOR}.${MINOR}.${PATCH}"
echo "tag=$NEW_TAG" >> "$GITHUB_OUTPUT"
echo "Previous version $LATEST → next version $NEW_TAG"

- name: Set snapshot SHA
id: snapshot
run: echo "sha=$(git rev-parse --short=8 HEAD)" >> "$GITHUB_OUTPUT"

- name: Check out gh-pages branch
id: checkout-gh-pages
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
ref: gh-pages
path: gh-pages
fetch-depth: 1
continue-on-error: true

- name: Verify snapshot exists for release
run: |
SHA="${{ steps.snapshot.outputs.sha }}"
if [ "${{ steps.checkout-gh-pages.outcome }}" != "success" ]; then
echo "::error::gh-pages branch does not exist; no snapshot available for commit $SHA"
exit 1
fi
if [ ! -d "gh-pages/p2/snapshots/$SHA" ]; then
echo "::error::No snapshot found for commit $SHA in p2/snapshots/; the commit must be built and deployed as a snapshot before releasing"
exit 1
fi
echo "Found snapshot for commit $SHA"

- name: Create and push tag
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
echo "Bumping to ${{ steps.version.outputs.tag }}"
git tag "${{ steps.version.outputs.tag }}"
git push origin "${{ steps.version.outputs.tag }}"

publish:
needs: create_tag
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
ref: ${{ needs.create_tag.outputs.tag }}
fetch-depth: 0

- name: Check out gh-pages branch
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
ref: gh-pages
path: gh-pages
fetch-depth: 1

- name: Publish p2 release to gh-pages
run: bash .github/scripts/publish-p2-ghpages.sh
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RELEASE_VERSION: ${{ needs.create_tag.outputs.tag }}
SNAPSHOT_SHA: ${{ needs.create_tag.outputs.snapshot_sha }}

- name: Create release with p2 update site
run: |
RELEASE_VERSION="${{ needs.create_tag.outputs.tag }}"
SNAPSHOT_SHA="${{ needs.create_tag.outputs.snapshot_sha }}"
mkdir -p release-staging/repository
cp -r "gh-pages/p2/snapshots/$SNAPSHOT_SHA/." release-staging/repository/
cd release-staging
zip -r p2-update-site.zip repository/
gh release create "$RELEASE_VERSION" \
p2-update-site.zip \
--generate-notes \
--title "Release ${RELEASE_VERSION#v}"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Summary
run: |
TAG="${{ needs.create_tag.outputs.tag }}"
REPO="${{ github.server_url }}/${{ github.repository }}"
echo "::notice::Created release $TAG from branch ${{ inputs.branch }}"
{
echo "## Release created"
echo ""
echo "| | |"
echo "|---|---|"
echo "| **Tag** | [$TAG]($REPO/releases/tag/$TAG) |"
echo "| **Branch** | \`${{ inputs.branch }}\` |"
echo "| **Bump** | \`${{ inputs.version_bump }}\` |"
} >> "$GITHUB_STEP_SUMMARY"

# Release workflow:
# Snapshots: every push to master or v[0-9]* branches → see snapshot.yml
# Release: workflow_dispatch → create tag, promote snapshot to p2/releases/<version>/
#
# p2 repository URLs (GitHub Pages):
# Latest snapshot: https://dsldevkit.github.io/dsl-devkit/p2/snapshots/latest/
# Pinned snapshot: https://dsldevkit.github.io/dsl-devkit/p2/snapshots/<sha>/
# Latest release: https://dsldevkit.github.io/dsl-devkit/p2/releases/latest/
# Pinned release: https://dsldevkit.github.io/dsl-devkit/p2/releases/{version}/
Loading