From 3602c26cd27cbfcacfb1eac1ab3971557ecf23c2 Mon Sep 17 00:00:00 2001 From: Jamkris Date: Fri, 27 Mar 2026 18:58:44 +0900 Subject: [PATCH 1/2] feat: implement tag-based release with version verification --- .github/workflows/release.yml | 91 ++++++++++++++++++++--------------- scripts/README.md | 1 + scripts/ko-KR/README.md | 1 + scripts/release.sh | 49 +++++++++++++++++++ 4 files changed, 102 insertions(+), 40 deletions(-) create mode 100755 scripts/release.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e9a289c..2394221 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,9 +1,9 @@ -name: Release on main merge +name: Release on: push: - branches: - - main + tags: + - 'v*' permissions: contents: write @@ -11,7 +11,7 @@ permissions: jobs: release: - name: Generate Release Notes and Create Release + name: Create Release runs-on: ubuntu-latest steps: @@ -20,13 +20,49 @@ jobs: with: fetch-depth: 0 - - name: Set up Git and fetch tags - run: git fetch --tags + - name: Validate version tag format + run: | + if ! [[ "${{ github.ref_name }}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "::error::Invalid version tag format (${{ github.ref_name }}). Expected vX.Y.Z" + exit 1 + fi + + - name: Verify versions match tag + env: + TAG_NAME: ${{ github.ref_name }} + run: | + TAG_VERSION="${TAG_NAME#v}" + + # Check package.json + PACKAGE_VERSION=$(node -p "require('./package.json').version") + if [ "$TAG_VERSION" != "$PACKAGE_VERSION" ]; then + echo "::error::Tag version ($TAG_VERSION) does not match package.json version ($PACKAGE_VERSION)" + exit 1 + fi + + # Check gemini-extension.json + EXTENSION_VERSION=$(node -p "require('./gemini-extension.json').version") + if [ "$TAG_VERSION" != "$EXTENSION_VERSION" ]; then + echo "::error::Tag version ($TAG_VERSION) does not match gemini-extension.json version ($EXTENSION_VERSION)" + exit 1 + fi + + # Check .gemini-plugin/plugin.json + PLUGIN_VERSION=$(node -p "require('./.gemini-plugin/plugin.json').version") + if [ "$TAG_VERSION" != "$PLUGIN_VERSION" ]; then + echo "::error::Tag version ($TAG_VERSION) does not match .gemini-plugin/plugin.json version ($PLUGIN_VERSION)" + exit 1 + fi + + echo "All versions match tag $TAG_NAME" - name: Get last tag and date id: get_last_tag run: | - LAST_TAG=$(git tag --list 'v[0-9]*' --sort=-v:refname | head -n 1) + # Get the tag before the current one + TAG_LIST=$(git tag --list 'v[0-9]*' --sort=-v:refname) + LAST_TAG=$(echo "$TAG_LIST" | sed -n '2p') + if [ -z "$LAST_TAG" ]; then LAST_TAG="v0.0.0" TAG_DATE="1970-01-01T00:00:00Z" @@ -36,7 +72,7 @@ jobs: echo "last_tag=$LAST_TAG" >> $GITHUB_OUTPUT echo "last_tag_date=$TAG_DATE" >> $GITHUB_OUTPUT - - name: Get merged PRs and their bodies + - name: Generate Changelog from merged PRs id: changelog uses: actions/github-script@v6 with: @@ -52,50 +88,25 @@ jobs: const since = new Date("${{ steps.get_last_tag.outputs.last_tag_date }}"); const mergedPRs = prs.filter(pr => pr.merged_at && new Date(pr.merged_at) > since); - let changelog = ""; + let changelog = "## What's Changed in ${{ github.ref_name }}\n\n"; if (mergedPRs.length === 0) { - changelog = "_No pull requests merged since last release._"; + changelog += "_No pull requests merged since last release._"; } else { const formatted = mergedPRs.map(pr => { const cleanBody = pr.body?.trim() || "_No description provided._"; return `### ${pr.title} (#${pr.number}) by @${pr.user.login}\n\n${cleanBody}`; }); - changelog = formatted.join("\n\n---\n\n"); + changelog += formatted.join("\n\n---\n\n"); } - // Write changelog to file to avoid context issues const fs = require('fs'); - fs.writeFileSync('CHANGELOG.md', changelog); - return changelog; - result-encoding: string - - - name: Bump Version and Push - id: versioning - run: | - # Calculate the next version from the last tag - LAST_TAG="${{ steps.get_last_tag.outputs.last_tag }}" - VERSION_NUM=${LAST_TAG#v} # Remove 'v' prefix for calculation - - IFS='.' read -r MAJOR MINOR PATCH <<< "$VERSION_NUM" - PATCH=$((PATCH + 1)) - NEW_VERSION="v$MAJOR.$MINOR.$PATCH" - - echo "Bumping version to $NEW_VERSION" - - git config user.name "Github-Release-Bot" - git config user.email "dltmdgus1412@gmail.com" - - # Create and push tag ONLY, avoiding push to protected main branch - git tag "$NEW_VERSION" - git push origin "$NEW_VERSION" - - echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT + fs.writeFileSync('RELEASE_NOTES.md', changelog); - name: Create GitHub Release uses: softprops/action-gh-release@v2 with: - tag_name: ${{ steps.versioning.outputs.version }} - name: ${{ steps.versioning.outputs.version }} - body_path: CHANGELOG.md + tag_name: ${{ github.ref_name }} + name: ${{ github.ref_name }} + body_path: RELEASE_NOTES.md env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/scripts/README.md b/scripts/README.md index 7356c1d..29e1391 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -16,6 +16,7 @@ This directory contains utility scripts for maintaining the Everything Gemini Co | Script | Description | |--------|-------------| | `harness-audit.js` | Audits the repository against core Gemini CLI harness rules. Checks for the presence of required context optimization documents, eval coverage, required hooks, and security guards.

**Usage:** `node scripts/harness-audit.js --scope repo` | +| `release.sh` | Synchronizes version numbers in `package.json`, `gemini-extension.json`, and `.gemini-plugin/plugin.json`, creates a git commit, and generates a version tag.

**Usage:** `./scripts/release.sh ` | ### Documentation Generation diff --git a/scripts/ko-KR/README.md b/scripts/ko-KR/README.md index 9a4a684..227c3b8 100644 --- a/scripts/ko-KR/README.md +++ b/scripts/ko-KR/README.md @@ -16,6 +16,7 @@ | 스크립트 | 설명 | |----------|------| | `harness-audit.js` | 핵심 Gemini CLI 규칙에 대한 저장소 상태를 검사(Audit)합니다. 토큰/컨텍스트 최적화 가이드 제공 여부, 훅 구성 파일, Eval 커버리지, 보안 가드레일 등을 평가합니다.

**사용법:** `node scripts/harness-audit.js --scope repo` | +| `release.sh` | `package.json`, `gemini-extension.json`, `.gemini-plugin/plugin.json` 세 파일의 버전을 동기화하고, 커밋 및 버전 태그(`v*`)를 생성합니다.

**사용법:** `./scripts/release.sh ` | ### 문서 자동 생성 diff --git a/scripts/release.sh b/scripts/release.sh new file mode 100755 index 0000000..8bc7b57 --- /dev/null +++ b/scripts/release.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +# ECC Release Helper Script +# Usage: ./scripts/release.sh +# Example: ./scripts/release.sh 1.1.2 + +set -e + +VERSION=$1 + +if [ -z "$VERSION" ]; then + echo "Usage: $0 " + echo "Example: $0 1.1.2" + exit 1 +fi + +# Remove 'v' prefix if provided +VERSION="${VERSION#v}" + +echo "Preparing release v$VERSION..." + +# 1. Update package.json +echo "Updating package.json..." +sed -i '' "s/\"version\": \".*\"/\"version\": \"$VERSION\"/" package.json + +# 2. Update gemini-extension.json +echo "Updating gemini-extension.json..." +sed -i '' "s/\"version\": \".*\"/\"version\": \"$VERSION\"/" gemini-extension.json + +# 3. Update .gemini-plugin/plugin.json +echo "Updating .gemini-plugin/plugin.json..." +sed -i '' "s/\"version\": \".*\"/\"version\": \"$VERSION\"/" .gemini-plugin/plugin.json + +echo "Versions updated to $VERSION in all configuration files." + +# 4. Git commit and tag +git add package.json gemini-extension.json .gemini-plugin/plugin.json + +echo "Committing version bump..." +git commit -m "chore: bump version to $VERSION" + +echo "Creating tag v$VERSION..." +git tag "v$VERSION" + +echo "Done!" +echo "Next steps:" +echo "1. git push origin main" +echo "2. git push origin v$VERSION" +echo "3. Check GitHub Actions for the Release process." From 481ddfca94b1a6f37003d9849d96ae907221eba7 Mon Sep 17 00:00:00 2001 From: Jamkris Date: Fri, 27 Mar 2026 18:59:19 +0900 Subject: [PATCH 2/2] chore: bump version to 1.2.0 --- .gemini-plugin/plugin.json | 2 +- gemini-extension.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.gemini-plugin/plugin.json b/.gemini-plugin/plugin.json index 7e251e0..0001fbe 100644 --- a/.gemini-plugin/plugin.json +++ b/.gemini-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "everything-gemini-code", - "version": "1.1.1", + "version": "1.2.0", "description": "Complete collection of battle-tested Gemini CLI configurations - agents, skills, hooks, and rules evolved over 10+ months of intensive daily use", "author": { "name": "Jamkris", diff --git a/gemini-extension.json b/gemini-extension.json index 760633c..a5a4603 100644 --- a/gemini-extension.json +++ b/gemini-extension.json @@ -1,6 +1,6 @@ { "name": "everything-gemini-code", - "version": "1.1.1", + "version": "1.2.0", "description": "Complete collection of Gemini CLI configurations adapted from everything-gemini-code - agents, skills, hooks, and rules", "author": { "name": "Jamkris", diff --git a/package.json b/package.json index 106e36a..ab48c4d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "everything-gemini-code", - "version": "1.1.1", + "version": "1.2.0", "private": true, "description": "Battle-tested Gemini CLI configurations", "author": "Jamkris",