feat(mr-review): add new skill for concise GitLab MR reviews with pre… #29
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Auto-publish changed skills | |
| # On any push to main that touches files under skills/<name>/ (excluding pom.xml), | |
| # detect which skills changed, bump each one's patch version, publish to Maven | |
| # Central via the Central Portal, then commit the version bumps back to main. | |
| # | |
| # The commit-back uses [skip ci] so it doesn't trigger another run. | |
| # | |
| # Manual override: trigger from the Actions tab with a skill name to force-publish | |
| # even if nothing changed. | |
| on: | |
| push: | |
| branches: [main] | |
| workflow_dispatch: | |
| inputs: | |
| skill: | |
| description: 'Skill name to force-publish (e.g. gitlab-helper)' | |
| required: false | |
| type: string | |
| permissions: | |
| contents: write | |
| concurrency: | |
| group: publish-${{ github.ref }} | |
| cancel-in-progress: false | |
| jobs: | |
| publish: | |
| runs-on: ubuntu-latest | |
| if: "!contains(github.event.head_commit.message, '[skip ci]')" | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 2 | |
| persist-credentials: true | |
| - name: Set up JDK 17 + GPG | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: temurin | |
| java-version: '17' | |
| server-id: central | |
| server-username: OSS_NEXUS_USER | |
| server-password: OSS_NEXUS_PASS | |
| gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} | |
| - name: Detect changed skills | |
| id: detect | |
| env: | |
| FORCE_SKILL: ${{ inputs.skill }} | |
| run: | | |
| set -e | |
| if [ -n "${FORCE_SKILL}" ]; then | |
| echo "Force-publishing: ${FORCE_SKILL}" | |
| echo "skills=${FORCE_SKILL}" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| if ! git rev-parse HEAD~1 >/dev/null 2>&1; then | |
| echo "No previous commit — nothing to diff." | |
| echo "skills=" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| # Any file change under skills/<name>/ triggers a bump for that | |
| # skill — including pom.xml. The workflow's own bump-commit carries | |
| # [skip ci] so it doesn't loop. | |
| CHANGED=$(git diff --name-only HEAD~1 HEAD -- 'skills/' \ | |
| | awk -F/ '/^skills\// && NF>=3 {print $2}' \ | |
| | sort -u \ | |
| | tr '\n' ' ') | |
| echo "Changed skills: '${CHANGED}'" | |
| echo "skills=${CHANGED}" >> "$GITHUB_OUTPUT" | |
| - name: Bump, build, publish | |
| id: publish | |
| if: steps.detect.outputs.skills != '' | |
| env: | |
| OSS_NEXUS_USER: ${{ secrets.OSS_NEXUS_USER }} | |
| OSS_NEXUS_PASS: ${{ secrets.OSS_NEXUS_PASS }} | |
| SKILLS: ${{ steps.detect.outputs.skills }} | |
| run: | | |
| # NOTE: deliberately NO `set -e` — we want the loop to continue | |
| # past a failure of one skill so the others still get a chance | |
| # to publish. We track failures separately and fail the step | |
| # at the end if any individual skill failed. | |
| PUBLISHED="" | |
| FAILED="" | |
| for skill in $SKILLS; do | |
| module="skills/${skill}" | |
| if [ ! -f "${module}/pom.xml" ]; then | |
| echo "::warning::No pom.xml for ${skill} — skipping" | |
| continue | |
| fi | |
| CURRENT=$(mvn -q -f "${module}/pom.xml" help:evaluate \ | |
| -Dexpression=project.version -DforceStdout) | |
| if [ -z "$CURRENT" ]; then | |
| echo "::error::could not read current version for ${skill}" | |
| FAILED="${FAILED}${skill}:version-read " | |
| continue | |
| fi | |
| IFS=. read -r MAJ MIN PAT <<<"${CURRENT}" | |
| NEW="${MAJ}.${MIN}.$((PAT + 1))" | |
| echo "::group::Publishing ${skill} ${CURRENT} -> ${NEW}" | |
| if ! mvn -B -ntp -pl "${module}" versions:set \ | |
| -DnewVersion="${NEW}" -DgenerateBackupPoms=false; then | |
| echo "::error::versions:set failed for ${skill}" | |
| FAILED="${FAILED}${skill}:versions-set " | |
| git checkout -- "${module}/pom.xml" 2>/dev/null || true | |
| echo "::endgroup::" | |
| continue | |
| fi | |
| if mvn -B -ntp -pl "${module}" -am -Prelease deploy; then | |
| PUBLISHED="${PUBLISHED}${skill}:${NEW} " | |
| echo "::notice title=Published::${skill} ${NEW}" | |
| else | |
| FAILED="${FAILED}${skill}:${NEW} " | |
| echo "::error title=Deploy failed::${skill} ${NEW}" | |
| # revert the version bump so we don't commit a version | |
| # that never actually shipped | |
| git checkout -- "${module}/pom.xml" 2>/dev/null || true | |
| fi | |
| echo "::endgroup::" | |
| done | |
| echo "published=${PUBLISHED}" >> "$GITHUB_OUTPUT" | |
| echo "failed=${FAILED}" >> "$GITHUB_OUTPUT" | |
| echo "Published: ${PUBLISHED:-(none)}" | |
| echo "Failed: ${FAILED:-(none)}" | |
| # Fail the step (red badge) if any skill failed — but only | |
| # AFTER attempting every skill. Downstream steps use | |
| # if:always() so successful publishes still get released. | |
| if [ -n "${FAILED}" ]; then | |
| exit 1 | |
| fi | |
| - name: Create GitHub release for each published skill | |
| # always() so that a partial-failure of the publish step (some | |
| # skills succeeded, some failed) still releases the successful ones. | |
| if: always() && steps.publish.outputs.published != '' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| PUBLISHED: ${{ steps.publish.outputs.published }} | |
| run: | | |
| set -e | |
| for entry in $PUBLISHED; do | |
| skill="${entry%%:*}" | |
| version="${entry##*:}" | |
| tag="${skill}-v${version}" | |
| zip="skills/${skill}/target/${skill}-${version}-bin.zip" | |
| echo "::group::Release ${tag}" | |
| # Build release notes from commits touching this skill since the previous tag. | |
| prev_tag=$(git tag --list "${skill}-v*" --sort=-v:refname | head -n1) | |
| if [ -n "$prev_tag" ]; then | |
| range="${prev_tag}..HEAD" | |
| else | |
| range="HEAD" | |
| fi | |
| notes=$(git log --pretty=format:'- %s' "$range" -- "skills/${skill}/" \ | |
| "assembly/" "pom.xml" ".github/workflows/publish.yml" | head -50) | |
| if [ -z "$notes" ]; then | |
| notes="- Initial release of ${skill} ${version}" | |
| fi | |
| body=$(printf '## %s %s\n\nPublished to Maven Central:\n```\nio.github.randomcodespace.ai.skills:%s:%s\n```\n\n### Changes\n%s\n' \ | |
| "$skill" "$version" "$skill" "$version" "$notes") | |
| gh release create "$tag" \ | |
| --title "${skill} ${version}" \ | |
| --notes "$body" \ | |
| --target "$(git rev-parse HEAD)" \ | |
| ${zip:+"$zip"} | |
| echo "::endgroup::" | |
| done | |
| - name: Commit version bumps | |
| # always() so that the successful skills' version bumps still | |
| # land in the repo even when some other skill failed to publish. | |
| if: always() && steps.detect.outputs.skills != '' | |
| run: | | |
| set -e | |
| if git diff --quiet -- 'skills/*/pom.xml'; then | |
| echo "No version changes to commit." | |
| exit 0 | |
| fi | |
| git config user.name "github-actions[bot]" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| git add skills/*/pom.xml | |
| git commit -m "chore: bump skill patch version after publish [skip ci]" | |
| git push origin HEAD:main |