From 5bf929491e76fb1da00b231a6ecd00403981a006 Mon Sep 17 00:00:00 2001 From: Joao Ferreira Date: Tue, 21 Apr 2026 16:16:22 +0200 Subject: [PATCH 1/2] fix: do not delete .gitignore files during maven clean phase --- ddk-parent/pom.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ddk-parent/pom.xml b/ddk-parent/pom.xml index ef5a04d713..555b34c469 100644 --- a/ddk-parent/pom.xml +++ b/ddk-parent/pom.xml @@ -373,6 +373,9 @@ ** + + .gitignore + From 6119f38cdcbb96ec0d7afafc6682f0ce7e413b13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Dinis=20Ferreira?= Date: Wed, 22 Apr 2026 01:27:04 +0200 Subject: [PATCH 2/2] ci: publish Maven artifacts and p2 update site On every push to master, build and deploy SNAPSHOT artifacts, publish the p2 update site to gh-pages (last 20 snapshots retained by SHA). Releases are triggered via workflow_dispatch (one-click) or by pushing a v* tag. The workflow creates GitHub Releases, maintains a p2/releases/latest/ alias (highest semver, not most recent), and opens a version-bump PR with smart logic encoding the project's 0-4 minor cycle. Patch releases from release branches are supported via tag push. Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/publish.yml | 304 ++++++++++++++++++++++++++++++++++ ddk-parent/pom.xml | 49 ++++++ 2 files changed, 353 insertions(+) create mode 100644 .github/workflows/publish.yml diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000000..b688842f5b --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,304 @@ +name: publish + +on: + workflow_dispatch: {} + push: + branches: [master] + tags: ['v*'] + +concurrency: + group: publish-ghpages-${{ github.repository }} + cancel-in-progress: false + +permissions: + contents: write + packages: write + pull-requests: write + +jobs: + publish: + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + fetch-depth: 0 + + - name: Set up JDK 21 + uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5 + with: + distribution: 'temurin' + java-version: '21' + server-id: github + + - name: Log tool versions + run: | + java --version + mvn --version + + - name: Set up workspace + run: echo "WORKSPACE=${{ github.workspace }}" >> $GITHUB_ENV + + - name: Cache Maven dependencies + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-publish-${{ hashFiles('**/pom.xml', '**/*.target') }} + restore-keys: | + ${{ runner.os }}-maven-publish- + ${{ runner.os }}-maven-0- + + - name: Determine release version + id: version + if: github.event_name == 'workflow_dispatch' || startsWith(github.ref, 'refs/tags/v') + run: | + CURRENT=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout -f ./ddk-parent/pom.xml) + EXPECTED="${CURRENT%-SNAPSHOT}" + + if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then + VERSION="$EXPECTED" + else + VERSION="${GITHUB_REF_NAME#v}" + if [ "$VERSION" != "$EXPECTED" ]; then + echo "::error::Tag version $VERSION does not match pom version $EXPECTED (from $CURRENT)" + exit 1 + fi + fi + + echo "RELEASE_VERSION=$VERSION" >> "$GITHUB_ENV" + echo "release=true" >> "$GITHUB_OUTPUT" + + - name: Prepare release + if: steps.version.outputs.release == 'true' + run: | + git config user.email "github-actions[bot]@users.noreply.github.com" + git config user.name "github-actions[bot]" + mvn -f ./ddk-parent/pom.xml \ + org.eclipse.tycho:tycho-versions-plugin:set-version \ + -DnewVersion="$RELEASE_VERSION" \ + --batch-mode + git add -A + git commit -m "Release $RELEASE_VERSION" + + if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then + git tag "v$RELEASE_VERSION" + git push origin "v$RELEASE_VERSION" + fi + + - name: Build and deploy + run: | + REPO_URL="https://maven.pkg.github.com/${{ github.repository }}" + xvfb-run mvn clean deploy \ + -f ./ddk-parent/pom.xml \ + -DreleaseRepoId=github \ + -DreleaseRepoName="GitHub Packages" \ + -DreleaseRepoUrl="$REPO_URL" \ + -DsnapshotRepoId=github \ + -DsnapshotRepoName="GitHub Packages" \ + -DsnapshotRepoUrl="$REPO_URL" \ + -Dp2ArtifactoryReleaseRepoId=github \ + -Dp2ArtifactoryReleaseRepoName="GitHub Packages" \ + -Dp2ArtifactoryReleaseRepoUrl="$REPO_URL" \ + -Dp2ArtifactorySnapshotRepoId=github \ + -Dp2ArtifactorySnapshotRepoName="GitHub Packages" \ + -Dp2ArtifactorySnapshotRepoUrl="$REPO_URL" \ + --batch-mode + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Upload p2 update site as artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + with: + name: p2-update-site-${{ github.sha }} + path: ddk-repository/target/repository/ + retention-days: 30 + + - 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: Bootstrap gh-pages branch if missing + if: steps.checkout-gh-pages.outcome != 'success' + run: | + rm -rf gh-pages + mkdir gh-pages + cd gh-pages + git init -b gh-pages + git remote add origin "https://x-access-token:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Publish p2 update site to gh-pages + run: | + cd gh-pages + git config user.email "github-actions[bot]@users.noreply.github.com" + git config user.name "github-actions[bot]" + + if [ -n "$RELEASE_VERSION" ]; then + TARGET="p2/releases/$RELEASE_VERSION" + REF_DESC="release $RELEASE_VERSION" + else + TARGET="p2/snapshots/${GITHUB_SHA::8}" + REF_DESC="snapshot ${GITHUB_SHA::8}" + fi + + rm -rf "$TARGET" + mkdir -p "$TARGET" + cp -r ../ddk-repository/target/repository/. "$TARGET/" + + if [ -n "$RELEASE_VERSION" ]; then + HIGHEST=$(ls -1 p2/releases | grep -v latest | sort -Vr | head -1) + rm -rf p2/releases/latest + cp -r "p2/releases/$HIGHEST" p2/releases/latest + else + rm -rf p2/snapshots/latest + cp -r "p2/snapshots/${GITHUB_SHA::8}" p2/snapshots/latest + # Prune snapshots to last 20 + if [ -d p2/snapshots ]; then + (cd p2/snapshots && ls -1t | grep -v latest | tail -n +21 | xargs -I{} rm -rf "{}") + fi + fi + + # Generate index.html + { + echo '' + echo '' + echo '

DSL DevKit p2 Repository

' + echo '

Snapshots

' + echo '
    ' + if [ -d p2/snapshots/latest ]; then + echo '
  • Latest Snapshot
  • ' + fi + if [ -d p2/snapshots ]; then + for s in $(cd p2/snapshots && ls -1t | grep -v latest | head -20); do + echo "
  • $s
  • " + done + fi + echo '
' + if [ -d p2/releases ] && [ -n "$(ls -A p2/releases 2>/dev/null)" ]; then + echo '

Releases

' + echo '
    ' + if [ -d p2/releases/latest ]; then + echo '
  • Latest Release
  • ' + fi + for v in $(ls -1 p2/releases | grep -v latest | sort -Vr); do + echo "
  • $v
  • " + done + echo '
' + fi + echo '' + } > 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 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create release with p2 update site + if: steps.version.outputs.release == 'true' + run: | + cd ddk-repository/target + zip -r p2-update-site.zip repository/ + gh release create "v$RELEASE_VERSION" \ + p2-update-site.zip \ + --generate-notes \ + --title "Release $RELEASE_VERSION" + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create version bump PR + if: steps.version.outputs.release == 'true' + run: | + git config user.email "github-actions[bot]@users.noreply.github.com" + git config user.name "github-actions[bot]" + rm -rf gh-pages + + MAJOR=$(echo "$RELEASE_VERSION" | cut -d. -f1) + MINOR=$(echo "$RELEASE_VERSION" | cut -d. -f2) + PATCH=$(echo "$RELEASE_VERSION" | cut -d. -f3) + + if [ "$PATCH" -gt 0 ]; then + NEXT="${MAJOR}.${MINOR}.$((PATCH + 1))-SNAPSHOT" + BASE_BRANCH="release/${MAJOR}.${MINOR}.x" + elif [ "$MINOR" -ge 4 ]; then + NEXT="$((MAJOR + 1)).0.0-SNAPSHOT" + BASE_BRANCH="master" + else + NEXT="${MAJOR}.$((MINOR + 1)).0-SNAPSHOT" + BASE_BRANCH="master" + fi + + git fetch origin "$BASE_BRANCH" + git checkout -f "$BASE_BRANCH" + mvn -f ./ddk-parent/pom.xml \ + org.eclipse.tycho:tycho-versions-plugin:set-version \ + -DnewVersion="$NEXT" \ + --batch-mode + BRANCH="chore/bump-$NEXT" + git checkout -b "$BRANCH" + git add -u + git commit -m "chore: bump to $NEXT" + git push origin "$BRANCH" --force + gh pr create \ + --base "$BASE_BRANCH" \ + --head "$BRANCH" \ + --title "chore: bump to $NEXT" \ + --body "Automated version bump after release $RELEASE_VERSION. Merge to start the next development cycle." + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Clean up old Maven snapshots + if: steps.version.outputs.release != 'true' + run: | + OWNER="${{ github.repository_owner }}" + KEEP=20 + echo "Pruning all but last $KEEP versions per package" + + ENTITY_TYPE=$(gh api "/users/$OWNER" -q '.type' 2>/dev/null || echo "User") + if [ "$ENTITY_TYPE" = "Organization" ]; then + API_PREFIX="/orgs/$OWNER" + else + API_PREFIX="/users/$OWNER" + fi + + gh api "$API_PREFIX/packages?package_type=maven" --paginate -q '.[].name' | \ + while read -r PKG; do + gh api "$API_PREFIX/packages/maven/$PKG/versions" --paginate \ + -q 'sort_by(.created_at) | reverse | .[].id' | tail -n +$((KEEP + 1)) | \ + while read -r VID; do + echo " Deleting $PKG version $VID" + gh api --method DELETE "$API_PREFIX/packages/maven/$PKG/versions/$VID" || true + done + done + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + +# Release workflow: +# Snapshots: every push to master → build, deploy, p2/snapshots// (last 20 kept) +# Release: click "Run workflow" or push v* tag → build, deploy, p2/releases// +# Bump: automatic PR after each release (0-4 minor cycle, then major) +# Patches: push v* tag from release/X.Y.x branch → bump PR targets release branch +# +# 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// +# Latest release: https://dsldevkit.github.io/dsl-devkit/p2/releases/latest/ +# Pinned release: https://dsldevkit.github.io/dsl-devkit/p2/releases/{version}/ diff --git a/ddk-parent/pom.xml b/ddk-parent/pom.xml index 555b34c469..a13b7c920b 100644 --- a/ddk-parent/pom.xml +++ b/ddk-parent/pom.xml @@ -56,6 +56,13 @@ 7.23.0 5.0.2 2.42.0 + + + error + + + https://dsldevkit.github.io/dsl-devkit/p2/releases/latest/ + true @@ -215,7 +222,17 @@ org.eclipse.tycho tycho-packaging-plugin ${tycho.version} + + + org.eclipse.tycho + tycho-buildtimestamp-jgit + ${tycho.version} + + + jgit + pom.xml + ${jgit.dirtyWorkingTree} 'v'yyyyMMdd-HHmm @@ -242,6 +259,26 @@ + + org.eclipse.tycho.extras + tycho-p2-extras-plugin + ${tycho.version} + + + compare-version-with-baselines + verify + + compare-version-with-baselines + + + + ${baseline.repo.url} + + ${baseline.skip} + + + + org.eclipse.tycho tycho-surefire-plugin @@ -425,5 +462,17 @@ x86_64 + + + local-dev + + + !env.CI + + + + warning + +