diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index b64aaa4..5da1bfd 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -78,22 +78,38 @@ jobs: echo "New version: $NEW_VERSION" - name: Commit version bump + id: commit run: | git add package.json CHANGELOG.md - git commit -m "chore: bump version to v${{ steps.version.outputs.new_version }}" - git push origin main + if git diff --cached --quiet; then + echo "No changes to commit (version may already be at target version)" + echo "committed=false" >> $GITHUB_OUTPUT + else + git commit -m "chore: bump version to v${{ steps.version.outputs.new_version }}" + git push origin main + echo "committed=true" >> $GITHUB_OUTPUT + fi - name: Create git tag for release + if: steps.commit.outputs.committed == 'true' run: | TAG_NAME="v${{ steps.version.outputs.new_version }}" echo "Creating tag $TAG_NAME" - git tag -a "$TAG_NAME" -m "Release $TAG_NAME" - git push origin "$TAG_NAME" + + # Check if tag already exists + if git rev-parse "$TAG_NAME" >/dev/null 2>&1; then + echo "Tag $TAG_NAME already exists, skipping tag creation" + else + git tag -a "$TAG_NAME" -m "Release $TAG_NAME" + git push origin "$TAG_NAME" + fi - name: Set up Docker Buildx + if: steps.commit.outputs.committed == 'true' uses: docker/setup-buildx-action@v3 - name: Build test-capable image + if: steps.commit.outputs.committed == 'true' run: | docker build \ --target test-runner \ @@ -102,6 +118,7 @@ jobs: . - name: Run tests inside test-capable container + if: steps.commit.outputs.committed == 'true' run: | docker run --rm \ -e DATABASE_URL="postgresql://user:pass@localhost:5432/dummy" \ @@ -109,6 +126,7 @@ jobs: npm run test:run - name: Build production image + if: steps.commit.outputs.committed == 'true' run: | docker build \ --target runner \ @@ -118,6 +136,7 @@ jobs: . - name: Push Docker images + if: steps.commit.outputs.committed == 'true' run: | echo "Pushing to ${{ env.REGISTRY }}..." # Check if we can authenticate to the registry using DOCKER_LOGIN and DOCKER_PASSWORD secrets @@ -142,6 +161,7 @@ jobs: fi - name: Deploy to dev (placeholder) + if: steps.commit.outputs.committed == 'true' run: | echo "Deploying version ${{ steps.version.outputs.new_version }} to dev environment..." # TODO: Add actual deployment steps diff --git a/scripts/bump-version.js b/scripts/bump-version.js index 989a4b7..80be566 100755 --- a/scripts/bump-version.js +++ b/scripts/bump-version.js @@ -48,14 +48,22 @@ function getCommitsSinceLastTag() { if (!latestTag) { // No tags yet, get all commits - return execSync('git log --oneline --format=%s', { encoding: 'utf8' }).trim().split('\n'); + const commits = execSync('git log --oneline --format=%s', { encoding: 'utf8' }).trim(); + return commits ? commits.split('\n') : []; } const commits = execSync(`git log ${latestTag}..HEAD --oneline --format=%s`, { encoding: 'utf8' }).trim(); return commits ? commits.split('\n') : []; } catch (error) { // If no commits since tag or other error, get recent commits - return execSync('git log --oneline --format=%s -n 20', { encoding: 'utf8' }).trim().split('\n'); + try { + const commits = execSync('git log --oneline --format=%s -n 20', { encoding: 'utf8' }).trim(); + return commits ? commits.split('\n') : []; + } catch (innerError) { + // If all git log attempts fail, return empty array + console.warn('Warning: Could not retrieve commit history, defaulting to patch version'); + return []; + } } } @@ -175,37 +183,47 @@ function main() { console.log(`New version: ${currentVersion} → ${newVersion}`); } - // Confirm with user - const readline = require('readline'); - const rl = readline.createInterface({ - input: process.stdin, - output: process.stdout - }); + // Confirm with user (or skip if --yes flag is set) + if (skipConfirm) { + // Update package.json + updatePackageJson(newVersion); - rl.question(`\nApply version ${newVersion}? (y/N) `, (answer) => { - if (answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes') { - // Update package.json - updatePackageJson(newVersion); - - // Update changelog - if (bumpType !== 'custom') { - const commits = getCommitsSinceLastTag(); - updateChangelog(newVersion, commits, bumpType); - } - - console.log(`\n✅ Version bumped to ${newVersion}`); - console.log(`\nNext steps:`); - console.log(` 1. Review changes: git diff`); - console.log(` 2. Commit changes: git commit -am "chore: bump version to v${newVersion}"`); - console.log(` 3. Create tag: git tag -a v${newVersion} -m "Release v${newVersion}"`); - console.log(` 4. Push changes: git push origin main`); - console.log(` 5. Push tag: git push origin v${newVersion}`); - } else { - console.log('❌ Version bump cancelled'); + // Update changelog + if (bumpType !== 'custom') { + const commits = getCommitsSinceLastTag(); + updateChangelog(newVersion, commits, bumpType); } - rl.close(); - }); + console.log(`\n✅ Version bumped to ${newVersion}`); + process.exit(0); + } else { + const readline = require('readline'); + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout + }); + + rl.question(`\nApply version ${newVersion}? (y/N) `, (answer) => { + if (answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes') { + // Update package.json + updatePackageJson(newVersion); + + // Update changelog + if (bumpType !== 'custom') { + const commits = getCommitsSinceLastTag(); + updateChangelog(newVersion, commits, bumpType); + } + + console.log(`\n✅ Version bumped to ${newVersion}`); + process.exit(0); + } else { + console.log('❌ Version bump cancelled'); + process.exit(1); + } + + rl.close(); + }); + } } // Run main function