Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0301212b9d | |||
| 272b8792cd | |||
| fd5341f14c |
@@ -97,13 +97,21 @@ jobs:
|
||||
- name: Install Rust toolchain (for building native Python packages)
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
- name: Cache pip wheel cache (for compiled packages like real_ladybug)
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/Library/Caches/pip
|
||||
key: pip-wheel-${{ runner.os }}-x64-${{ hashFiles('apps/backend/requirements.txt') }}
|
||||
restore-keys: |
|
||||
pip-wheel-${{ runner.os }}-x64-
|
||||
|
||||
- name: Cache bundled Python
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: apps/frontend/python-runtime
|
||||
key: python-bundle-${{ runner.os }}-x64-3.12.8-rust
|
||||
key: python-bundle-${{ runner.os }}-x64-3.12.8-rust-${{ hashFiles('apps/backend/requirements.txt') }}
|
||||
restore-keys: |
|
||||
python-bundle-${{ runner.os }}-x64-
|
||||
python-bundle-${{ runner.os }}-x64-3.12.8-rust-
|
||||
|
||||
- name: Build application
|
||||
run: cd apps/frontend && npm run build
|
||||
@@ -181,13 +189,21 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: cd apps/frontend && npm ci
|
||||
|
||||
- name: Cache pip wheel cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/Library/Caches/pip
|
||||
key: pip-wheel-${{ runner.os }}-arm64-${{ hashFiles('apps/backend/requirements.txt') }}
|
||||
restore-keys: |
|
||||
pip-wheel-${{ runner.os }}-arm64-
|
||||
|
||||
- name: Cache bundled Python
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: apps/frontend/python-runtime
|
||||
key: python-bundle-${{ runner.os }}-arm64-3.12.8
|
||||
key: python-bundle-${{ runner.os }}-arm64-3.12.8-${{ hashFiles('apps/backend/requirements.txt') }}
|
||||
restore-keys: |
|
||||
python-bundle-${{ runner.os }}-arm64-
|
||||
python-bundle-${{ runner.os }}-arm64-3.12.8-
|
||||
|
||||
- name: Build application
|
||||
run: cd apps/frontend && npm run build
|
||||
@@ -265,13 +281,21 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: cd apps/frontend && npm ci
|
||||
|
||||
- name: Cache pip wheel cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~\AppData\Local\pip\Cache
|
||||
key: pip-wheel-${{ runner.os }}-x64-${{ hashFiles('apps/backend/requirements.txt') }}
|
||||
restore-keys: |
|
||||
pip-wheel-${{ runner.os }}-x64-
|
||||
|
||||
- name: Cache bundled Python
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: apps/frontend/python-runtime
|
||||
key: python-bundle-${{ runner.os }}-x64-3.12.8
|
||||
key: python-bundle-${{ runner.os }}-x64-3.12.8-${{ hashFiles('apps/backend/requirements.txt') }}
|
||||
restore-keys: |
|
||||
python-bundle-${{ runner.os }}-x64-
|
||||
python-bundle-${{ runner.os }}-x64-3.12.8-
|
||||
|
||||
- name: Build application
|
||||
run: cd apps/frontend && npm run build
|
||||
@@ -335,13 +359,21 @@ jobs:
|
||||
flatpak install -y --user flathub org.freedesktop.Platform//25.08 org.freedesktop.Sdk//25.08
|
||||
flatpak install -y --user flathub org.electronjs.Electron2.BaseApp//25.08
|
||||
|
||||
- name: Cache pip wheel cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: pip-wheel-${{ runner.os }}-x64-${{ hashFiles('apps/backend/requirements.txt') }}
|
||||
restore-keys: |
|
||||
pip-wheel-${{ runner.os }}-x64-
|
||||
|
||||
- name: Cache bundled Python
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: apps/frontend/python-runtime
|
||||
key: python-bundle-${{ runner.os }}-x64-3.12.8
|
||||
key: python-bundle-${{ runner.os }}-x64-3.12.8-${{ hashFiles('apps/backend/requirements.txt') }}
|
||||
restore-keys: |
|
||||
python-bundle-${{ runner.os }}-x64-
|
||||
python-bundle-${{ runner.os }}-x64-3.12.8-
|
||||
|
||||
- name: Build application
|
||||
run: cd apps/frontend && npm run build
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
name: Prepare Release
|
||||
|
||||
# Triggers when code is pushed to main (e.g., merging develop → main)
|
||||
# If package.json version is newer than the latest tag, creates a new tag
|
||||
# which then triggers the release.yml workflow
|
||||
# If package.json version is newer than the latest tag:
|
||||
# 1. Validates CHANGELOG.md has an entry for this version (FAILS if missing)
|
||||
# 2. Extracts release notes from CHANGELOG.md
|
||||
# 3. Creates a new tag which triggers release.yml
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -67,8 +69,122 @@ jobs:
|
||||
echo "⏭️ No release needed (package version not newer than latest tag)"
|
||||
fi
|
||||
|
||||
- name: Create and push tag
|
||||
# CRITICAL: Validate CHANGELOG.md has entry for this version BEFORE creating tag
|
||||
- name: Validate and extract changelog
|
||||
if: steps.check.outputs.should_release == 'true'
|
||||
id: changelog
|
||||
run: |
|
||||
VERSION="${{ steps.check.outputs.new_version }}"
|
||||
CHANGELOG_FILE="CHANGELOG.md"
|
||||
|
||||
echo "🔍 Validating CHANGELOG.md for version $VERSION..."
|
||||
|
||||
if [ ! -f "$CHANGELOG_FILE" ]; then
|
||||
echo "::error::CHANGELOG.md not found! Please create CHANGELOG.md with release notes."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract changelog section for this version
|
||||
# Looks for "## X.Y.Z" header and captures until next "## " or "---" or end
|
||||
CHANGELOG_CONTENT=$(awk -v ver="$VERSION" '
|
||||
BEGIN { found=0; content="" }
|
||||
/^## / {
|
||||
if (found) exit
|
||||
# Match version at start of header (e.g., "## 2.7.3 -" or "## 2.7.3")
|
||||
if ($2 == ver || $2 ~ "^"ver"[[:space:]]*-") {
|
||||
found=1
|
||||
# Skip the header line itself, we will add our own
|
||||
next
|
||||
}
|
||||
}
|
||||
/^---$/ { if (found) exit }
|
||||
found { content = content $0 "\n" }
|
||||
END {
|
||||
if (!found) {
|
||||
print "NOT_FOUND"
|
||||
exit 1
|
||||
}
|
||||
# Trim leading/trailing whitespace
|
||||
gsub(/^[[:space:]]+|[[:space:]]+$/, "", content)
|
||||
print content
|
||||
}
|
||||
' "$CHANGELOG_FILE")
|
||||
|
||||
if [ "$CHANGELOG_CONTENT" = "NOT_FOUND" ] || [ -z "$CHANGELOG_CONTENT" ]; then
|
||||
echo ""
|
||||
echo "::error::═══════════════════════════════════════════════════════════════════════"
|
||||
echo "::error:: CHANGELOG VALIDATION FAILED"
|
||||
echo "::error::═══════════════════════════════════════════════════════════════════════"
|
||||
echo "::error::"
|
||||
echo "::error:: Version $VERSION not found in CHANGELOG.md!"
|
||||
echo "::error::"
|
||||
echo "::error:: Before releasing, please update CHANGELOG.md with an entry like:"
|
||||
echo "::error::"
|
||||
echo "::error:: ## $VERSION - Your Release Title"
|
||||
echo "::error::"
|
||||
echo "::error:: ### ✨ New Features"
|
||||
echo "::error:: - Feature description"
|
||||
echo "::error::"
|
||||
echo "::error:: ### 🐛 Bug Fixes"
|
||||
echo "::error:: - Fix description"
|
||||
echo "::error::"
|
||||
echo "::error::═══════════════════════════════════════════════════════════════════════"
|
||||
echo ""
|
||||
|
||||
# Also add to job summary for visibility
|
||||
echo "## ❌ Release Blocked: Missing Changelog" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "Version **$VERSION** was not found in CHANGELOG.md." >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "### How to fix:" >> $GITHUB_STEP_SUMMARY
|
||||
echo "1. Update CHANGELOG.md with release notes for version $VERSION" >> $GITHUB_STEP_SUMMARY
|
||||
echo "2. Commit and push the changes" >> $GITHUB_STEP_SUMMARY
|
||||
echo "3. The release will automatically retry" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "### Expected format:" >> $GITHUB_STEP_SUMMARY
|
||||
echo "\`\`\`markdown" >> $GITHUB_STEP_SUMMARY
|
||||
echo "## $VERSION - Release Title" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "### ✨ New Features" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- Feature description" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "### 🐛 Bug Fixes" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- Fix description" >> $GITHUB_STEP_SUMMARY
|
||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ Found changelog entry for version $VERSION"
|
||||
echo ""
|
||||
echo "--- Extracted Release Notes ---"
|
||||
echo "$CHANGELOG_CONTENT"
|
||||
echo "--- End Release Notes ---"
|
||||
|
||||
# Save changelog to file for artifact upload
|
||||
echo "$CHANGELOG_CONTENT" > changelog-extract.md
|
||||
|
||||
# Also save to output (for short changelogs)
|
||||
# Using heredoc for multiline output
|
||||
{
|
||||
echo "content<<CHANGELOG_EOF"
|
||||
echo "$CHANGELOG_CONTENT"
|
||||
echo "CHANGELOG_EOF"
|
||||
} >> $GITHUB_OUTPUT
|
||||
|
||||
echo "changelog_valid=true" >> $GITHUB_OUTPUT
|
||||
|
||||
# Upload changelog as artifact for release.yml to use
|
||||
- name: Upload changelog artifact
|
||||
if: steps.check.outputs.should_release == 'true' && steps.changelog.outputs.changelog_valid == 'true'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: changelog-${{ steps.check.outputs.new_version }}
|
||||
path: changelog-extract.md
|
||||
retention-days: 1
|
||||
|
||||
- name: Create and push tag
|
||||
if: steps.check.outputs.should_release == 'true' && steps.changelog.outputs.changelog_valid == 'true'
|
||||
run: |
|
||||
VERSION="${{ steps.check.outputs.new_version }}"
|
||||
TAG="v$VERSION"
|
||||
@@ -85,17 +201,19 @@ jobs:
|
||||
|
||||
- name: Summary
|
||||
run: |
|
||||
if [ "${{ steps.check.outputs.should_release }}" = "true" ]; then
|
||||
if [ "${{ steps.check.outputs.should_release }}" = "true" ] && [ "${{ steps.changelog.outputs.changelog_valid }}" = "true" ]; then
|
||||
echo "## 🚀 Release Triggered" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "**Version:** v${{ steps.check.outputs.new_version }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "✅ Changelog validated and extracted from CHANGELOG.md" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "The release workflow has been triggered and will:" >> $GITHUB_STEP_SUMMARY
|
||||
echo "1. Build binaries for all platforms" >> $GITHUB_STEP_SUMMARY
|
||||
echo "2. Generate changelog from PRs" >> $GITHUB_STEP_SUMMARY
|
||||
echo "2. Use changelog from CHANGELOG.md" >> $GITHUB_STEP_SUMMARY
|
||||
echo "3. Create GitHub release" >> $GITHUB_STEP_SUMMARY
|
||||
echo "4. Update README with new version" >> $GITHUB_STEP_SUMMARY
|
||||
else
|
||||
elif [ "${{ steps.check.outputs.should_release }}" = "false" ]; then
|
||||
echo "## ⏭️ No Release Needed" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "**Package version:** ${{ steps.package.outputs.version }}" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
+105
-17
@@ -1,4 +1,5 @@
|
||||
name: Release
|
||||
# Triggers on version tags (v*) to build and publish releases
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -46,13 +47,21 @@ jobs:
|
||||
- name: Install Rust toolchain (for building native Python packages)
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
- name: Cache pip wheel cache (for compiled packages like real_ladybug)
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/Library/Caches/pip
|
||||
key: pip-wheel-${{ runner.os }}-x64-${{ hashFiles('apps/backend/requirements.txt') }}
|
||||
restore-keys: |
|
||||
pip-wheel-${{ runner.os }}-x64-
|
||||
|
||||
- name: Cache bundled Python
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: apps/frontend/python-runtime
|
||||
key: python-bundle-${{ runner.os }}-x64-3.12.8-rust
|
||||
key: python-bundle-${{ runner.os }}-x64-3.12.8-rust-${{ hashFiles('apps/backend/requirements.txt') }}
|
||||
restore-keys: |
|
||||
python-bundle-${{ runner.os }}-x64-
|
||||
python-bundle-${{ runner.os }}-x64-3.12.8-rust-
|
||||
|
||||
- name: Build application
|
||||
run: cd apps/frontend && npm run build
|
||||
@@ -123,13 +132,21 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: cd apps/frontend && npm ci
|
||||
|
||||
- name: Cache pip wheel cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/Library/Caches/pip
|
||||
key: pip-wheel-${{ runner.os }}-arm64-${{ hashFiles('apps/backend/requirements.txt') }}
|
||||
restore-keys: |
|
||||
pip-wheel-${{ runner.os }}-arm64-
|
||||
|
||||
- name: Cache bundled Python
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: apps/frontend/python-runtime
|
||||
key: python-bundle-${{ runner.os }}-arm64-3.12.8
|
||||
key: python-bundle-${{ runner.os }}-arm64-3.12.8-${{ hashFiles('apps/backend/requirements.txt') }}
|
||||
restore-keys: |
|
||||
python-bundle-${{ runner.os }}-arm64-
|
||||
python-bundle-${{ runner.os }}-arm64-3.12.8-
|
||||
|
||||
- name: Build application
|
||||
run: cd apps/frontend && npm run build
|
||||
@@ -200,13 +217,21 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: cd apps/frontend && npm ci
|
||||
|
||||
- name: Cache pip wheel cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~\AppData\Local\pip\Cache
|
||||
key: pip-wheel-${{ runner.os }}-x64-${{ hashFiles('apps/backend/requirements.txt') }}
|
||||
restore-keys: |
|
||||
pip-wheel-${{ runner.os }}-x64-
|
||||
|
||||
- name: Cache bundled Python
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: apps/frontend/python-runtime
|
||||
key: python-bundle-${{ runner.os }}-x64-3.12.8
|
||||
key: python-bundle-${{ runner.os }}-x64-3.12.8-${{ hashFiles('apps/backend/requirements.txt') }}
|
||||
restore-keys: |
|
||||
python-bundle-${{ runner.os }}-x64-
|
||||
python-bundle-${{ runner.os }}-x64-3.12.8-
|
||||
|
||||
- name: Build application
|
||||
run: cd apps/frontend && npm run build
|
||||
@@ -261,13 +286,21 @@ jobs:
|
||||
flatpak install -y --user flathub org.freedesktop.Platform//25.08 org.freedesktop.Sdk//25.08
|
||||
flatpak install -y --user flathub org.electronjs.Electron2.BaseApp//25.08
|
||||
|
||||
- name: Cache pip wheel cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: pip-wheel-${{ runner.os }}-x64-${{ hashFiles('apps/backend/requirements.txt') }}
|
||||
restore-keys: |
|
||||
pip-wheel-${{ runner.os }}-x64-
|
||||
|
||||
- name: Cache bundled Python
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: apps/frontend/python-runtime
|
||||
key: python-bundle-${{ runner.os }}-x64-3.12.8
|
||||
key: python-bundle-${{ runner.os }}-x64-3.12.8-${{ hashFiles('apps/backend/requirements.txt') }}
|
||||
restore-keys: |
|
||||
python-bundle-${{ runner.os }}-x64-
|
||||
python-bundle-${{ runner.os }}-x64-3.12.8-
|
||||
|
||||
- name: Build application
|
||||
run: cd apps/frontend && npm run build
|
||||
@@ -473,23 +506,77 @@ jobs:
|
||||
cat release-assets/checksums.sha256 >> $GITHUB_STEP_SUMMARY
|
||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
- name: Generate changelog
|
||||
if: ${{ github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.dry_run != true) }}
|
||||
- name: Extract changelog from CHANGELOG.md
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
id: changelog
|
||||
uses: release-drafter/release-drafter@v6
|
||||
with:
|
||||
config-name: release-drafter.yml
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
# Extract version from tag (v2.7.2 -> 2.7.2)
|
||||
VERSION=${GITHUB_REF_NAME#v}
|
||||
CHANGELOG_FILE="CHANGELOG.md"
|
||||
|
||||
echo "📋 Extracting release notes for version $VERSION from CHANGELOG.md..."
|
||||
|
||||
if [ ! -f "$CHANGELOG_FILE" ]; then
|
||||
echo "::warning::CHANGELOG.md not found, using minimal release notes"
|
||||
echo "body=Release v$VERSION" >> $GITHUB_OUTPUT
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Extract changelog section for this version
|
||||
# Looks for "## X.Y.Z" header and captures until next "## " or "---"
|
||||
CHANGELOG_CONTENT=$(awk -v ver="$VERSION" '
|
||||
BEGIN { found=0; content="" }
|
||||
/^## / {
|
||||
if (found) exit
|
||||
# Match version at start of header (e.g., "## 2.7.3 -" or "## 2.7.3")
|
||||
if ($2 == ver || $2 ~ "^"ver"[[:space:]]*-") {
|
||||
found=1
|
||||
next
|
||||
}
|
||||
}
|
||||
/^---$/ { if (found) exit }
|
||||
found { content = content $0 "\n" }
|
||||
END {
|
||||
if (!found) {
|
||||
print "NOT_FOUND"
|
||||
exit 0
|
||||
}
|
||||
# Trim leading/trailing whitespace
|
||||
gsub(/^[[:space:]]+|[[:space:]]+$/, "", content)
|
||||
print content
|
||||
}
|
||||
' "$CHANGELOG_FILE")
|
||||
|
||||
if [ "$CHANGELOG_CONTENT" = "NOT_FOUND" ] || [ -z "$CHANGELOG_CONTENT" ]; then
|
||||
echo "::warning::Version $VERSION not found in CHANGELOG.md, using minimal release notes"
|
||||
REPO="${{ github.repository }}"
|
||||
CHANGELOG_CONTENT="Release v$VERSION"$'\n\n'"See [CHANGELOG.md](https://github.com/${REPO}/blob/main/CHANGELOG.md) for details."
|
||||
fi
|
||||
|
||||
echo "✅ Extracted changelog content"
|
||||
|
||||
# Save to file first (more reliable for multiline)
|
||||
echo "$CHANGELOG_CONTENT" > changelog-body.md
|
||||
|
||||
# Use file-based output for multiline content
|
||||
{
|
||||
echo "body<<CHANGELOG_EOF"
|
||||
cat changelog-body.md
|
||||
echo "CHANGELOG_EOF"
|
||||
} >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Create Release
|
||||
if: ${{ github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.dry_run != true) }}
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
body: |
|
||||
${{ steps.changelog.outputs.body }}
|
||||
|
||||
---
|
||||
|
||||
${{ steps.virustotal.outputs.vt_results }}
|
||||
|
||||
**Full Changelog**: https://github.com/${{ github.repository }}/blob/main/CHANGELOG.md
|
||||
files: release-assets/*
|
||||
draft: false
|
||||
prerelease: ${{ contains(github.ref, 'beta') || contains(github.ref, 'alpha') }}
|
||||
@@ -500,7 +587,8 @@ jobs:
|
||||
update-readme:
|
||||
needs: [create-release]
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.dry_run != true) }}
|
||||
# Only update README on actual releases (tag push), not dry runs
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
|
||||
+280
@@ -1,3 +1,283 @@
|
||||
## 2.7.2 - Stability & Performance Enhancements
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
- Added refresh button to Kanban board for manually reloading tasks
|
||||
|
||||
- Terminal dropdown with built-in and external options in task review
|
||||
|
||||
- Centralized CLI tool path management with customizable settings
|
||||
|
||||
- Files tab in task details panel for better file organization
|
||||
|
||||
- Enhanced PR review page with filtering capabilities
|
||||
|
||||
- GitLab integration support
|
||||
|
||||
- Automated PR review with follow-up support and structured outputs
|
||||
|
||||
- UI scale feature with 75-200% range for accessibility
|
||||
|
||||
- Python 3.12 bundled with packaged Electron app
|
||||
|
||||
- OpenRouter support as LLM/embedding provider
|
||||
|
||||
- Internationalization (i18n) system for multi-language support
|
||||
|
||||
- Flatpak packaging support for Linux
|
||||
|
||||
- Path-aware AI merge resolution with device code streaming
|
||||
|
||||
### 🛠️ Improvements
|
||||
|
||||
- Improved terminal experience with persistent state when switching projects
|
||||
|
||||
- Enhanced PR review with structured outputs and fork support
|
||||
|
||||
- Better UX for display and scaling changes
|
||||
|
||||
- Convert synchronous I/O to async operations in worktree handlers
|
||||
|
||||
- Enhanced logs for commit linting stage
|
||||
|
||||
- Remove top navigation bars for cleaner UI
|
||||
|
||||
- Enhanced PR detail area visual design
|
||||
|
||||
- Improved CLI tool detection with more language support
|
||||
|
||||
- Added iOS/Swift project detection
|
||||
|
||||
- Optimize performance by removing projectTabs from useEffect dependencies
|
||||
|
||||
- Improved Python detection and version validation for compatibility
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- Fixed CI Python setup and PR status gate checks
|
||||
|
||||
- Fixed cross-platform CLI path detection and clearing in settings
|
||||
|
||||
- Preserve original task description after spec creation
|
||||
|
||||
- Fixed learning loop to retrieve patterns and gotchas from memory
|
||||
|
||||
- Resolved frontend lag and updated dependencies
|
||||
|
||||
- Fixed Content-Security-Policy to allow external HTTPS images
|
||||
|
||||
- Fixed PR review isolation by using temporary worktree
|
||||
|
||||
- Fixed Homebrew Python detection to prefer versioned Python over system python3
|
||||
|
||||
- Added support for Bun 1.2.0+ lock file format detection
|
||||
|
||||
- Fixed infinite re-render loop in task selection
|
||||
|
||||
- Fixed infinite loop in task detail merge preview loading
|
||||
|
||||
- Resolved Windows EINVAL error when opening worktree in VS Code
|
||||
|
||||
- Fixed fallback to prevent tasks stuck in ai_review status
|
||||
|
||||
- Fixed SDK permissions to include spec_dir
|
||||
|
||||
- Added --base-branch argument support to spec_runner
|
||||
|
||||
- Allow Windows to run CC PR Reviewer
|
||||
|
||||
- Fixed model selection to respect task_metadata.json
|
||||
|
||||
- Improved GitHub PR review by passing repo parameter explicitly
|
||||
|
||||
- Fixed electron-log imports with .js extension
|
||||
|
||||
- Fixed Swift detection order in project analyzer
|
||||
|
||||
- Prevent TaskEditDialog from unmounting when opened
|
||||
|
||||
- Fixed subprocess handling for Python paths with spaces
|
||||
|
||||
- Fixed file system race conditions and unused variables in security scanning
|
||||
|
||||
- Resolved Python detection and backend packaging issues
|
||||
|
||||
- Fixed version-specific links in README and pre-commit hooks
|
||||
|
||||
- Fixed task status persistence reverting on refresh
|
||||
|
||||
- Proper semver comparison for pre-release versions
|
||||
|
||||
- Use virtual environment Python for all services to fix dotenv errors
|
||||
|
||||
- Fixed explicit Windows System32 tar path for builds
|
||||
|
||||
- Added augmented PATH environment to all GitHub CLI calls
|
||||
|
||||
- Use PowerShell for tar extraction on Windows
|
||||
|
||||
- Added --force-local flag to tar on Windows
|
||||
|
||||
- Stop tracking spec files in git
|
||||
|
||||
- Fixed GitHub API calls with explicit GET method for comment fetches
|
||||
|
||||
- Support archiving tasks across all worktree locations
|
||||
|
||||
- Validated backend source path before using it
|
||||
|
||||
- Resolved spawn Python ENOENT error on Linux
|
||||
|
||||
- Fixed CodeQL alerts for uncontrolled command line
|
||||
|
||||
- Resolved GitHub follow-up review API issues
|
||||
|
||||
- Fixed relative path normalization to POSIX format
|
||||
|
||||
- Accepted bug_fix workflow_type alias during planning
|
||||
|
||||
- Added global spec numbering lock to prevent collisions
|
||||
|
||||
- Fixed ideation status sync
|
||||
|
||||
- Stopped running process when task status changes away from in_progress
|
||||
|
||||
- Removed legacy path from auto-claude source detection
|
||||
|
||||
- Resolved Python environment race condition
|
||||
|
||||
---
|
||||
|
||||
## What's Changed
|
||||
|
||||
- fix(ci): add Python setup to beta-release and fix PR status gate checks (#565) by @Andy in c2148bb9
|
||||
- fix: detect and clear cross-platform CLI paths in settings (#535) by @Andy in 29e45505
|
||||
- fix(ui): preserve original task description after spec creation (#536) by @Andy in 7990dcb4
|
||||
- fix(memory): fix learning loop to retrieve patterns and gotchas (#530) by @Andy in f58c2578
|
||||
- fix: resolve frontend lag and update dependencies (#526) by @Andy in 30f7951a
|
||||
- feat(kanban): add refresh button to manually reload tasks (#548) by @Adryan Serage in 252242f9
|
||||
- fix(csp): allow external HTTPS images in Content-Security-Policy (#549) by @Michael Ludlow in 3db02c5d
|
||||
- fix(pr-review): use temporary worktree for PR review isolation (#532) by @Andy in 344ec65e
|
||||
- fix: prefer versioned Homebrew Python over system python3 (#494) by @Navid in 8d58dd6f
|
||||
- fix(detection): support bun.lock text format for Bun 1.2.0+ (#525) by @Andy in 4da8cd66
|
||||
- chore: bump version to 2.7.2-beta.12 (#460) by @Andy in 8e5c11ac
|
||||
- Fix/windows issues (#471) by @Andy in 72106109
|
||||
- fix(ci): add Rust toolchain for Intel Mac builds (#459) by @Andy in 52a4fcc6
|
||||
- fix: create spec.md during roadmap-to-task conversion (#446) by @Mulaveesala Pranaveswar in fb6b7fc6
|
||||
- fix(pr-review): treat LOW-only findings as ready to merge (#455) by @Andy in 0f9c5b84
|
||||
- Fix/2.7.2 beta12 (#424) by @Andy in 5d8ede23
|
||||
- feat: remove top bars (#386) by @Vinícius Santos in da31b687
|
||||
- fix: prevent infinite re-render loop in task selection useEffect (#442) by @Abe Diaz in 2effa535
|
||||
- fix: accept Python 3.12+ in install-backend.js (#443) by @Abe Diaz in c15bb311
|
||||
- fix: infinite loop in useTaskDetail merge preview loading (#444) by @Abe Diaz in 203a970a
|
||||
- fix(windows): resolve EINVAL error when opening worktree in VS Code (#434) by @Vinícius Santos in 3c0708b7
|
||||
- feat(frontend): Add Files tab to task details panel (#430) by @Mitsu in 666794b5
|
||||
- refactor: remove deprecated TaskDetailPanel component (#432) by @Mitsu in ac8dfcac
|
||||
- fix(ui): add fallback to prevent tasks stuck in ai_review status (#397) by @Michael Ludlow in 798ca79d
|
||||
- feat: Enhance the look of the PR Detail area (#427) by @Alex in bdb01549
|
||||
- ci: remove conventional commits PR title validation workflow by @AndyMik90 in 515b73b5
|
||||
- fix(client): add spec_dir to SDK permissions (#429) by @Mitsu in 88c76059
|
||||
- fix(spec_runner): add --base-branch argument support (#428) by @Mitsu in 62a75515
|
||||
- feat: enhance pr review page to include PRs filters (#423) by @Alex in 717fba04
|
||||
- feat: add gitlab integration (#254) by @Mitsu in 0a571d3a
|
||||
- fix: Allow windows to run CC PR Reviewer (#406) by @Alex in 2f662469
|
||||
- fix(model): respect task_metadata.json model selection (#415) by @Andy in e7e6b521
|
||||
- feat(build): add Flatpak packaging support for Linux (#404) by @Mitsu in 230de5fc
|
||||
- fix(github): pass repo parameter to GHClient for explicit PR resolution (#413) by @Andy in 4bdf7a0c
|
||||
- chore(ci): remove redundant CLA GitHub Action workflow by @AndyMik90 in a39ea49d
|
||||
- fix(frontend): add .js extension to electron-log/main imports by @AndyMik90 in 9aef0dd0
|
||||
- fix: 2.7.2 bug fixes and improvements (#388) by @Andy in 05131217
|
||||
- fix(analyzer): move Swift detection before Ruby detection (#401) by @Michael Ludlow in 321c9712
|
||||
- fix(ui): prevent TaskEditDialog from unmounting when opened (#395) by @Michael Ludlow in 98b12ed8
|
||||
- fix: improve CLI tool detection and add Claude CLI path settings (#393) by @Joe in aaa83131
|
||||
- feat(analyzer): add iOS/Swift project detection (#389) by @Michael Ludlow in 68548e33
|
||||
- fix(github): improve PR review with structured outputs and fork support (#363) by @Andy in 7751588e
|
||||
- fix(ideation): update progress calculation to include just-completed ideation type (#381) by @Illia Filippov in 8b4ce58c
|
||||
- Fixes failing spec - "gh CLI Check Handler - should return installed: true when gh CLI is found" (#370) by @Ian in bc220645
|
||||
- fix: Memory Status card respects configured embedding provider (#336) (#373) by @Michael Ludlow in db0cbea3
|
||||
- fix: fixed version-specific links in readme and pre-commit hook that updates them (#378) by @Ian in 0ca2e3f6
|
||||
- docs: add security research documentation (#361) by @Brian in 2d3b7fb4
|
||||
- fix/Improving UX for Display/Scaling Changes (#332) by @Kevin Rajan in 9bbdef09
|
||||
- fix(perf): remove projectTabs from useEffect deps to fix re-render loop (#362) by @Michael Ludlow in 753dc8bb
|
||||
- fix(security): invalidate profile cache when file is created/modified (#355) by @Michael Ludlow in 20f20fa3
|
||||
- fix(subprocess): handle Python paths with spaces (#352) by @Michael Ludlow in eabe7c7d
|
||||
- fix: Resolve pre-commit hook failures with version sync, pytest path, ruff version, and broken quality-dco workflow (#334) by @Ian in 1fa7a9c7
|
||||
- fix(terminal): preserve terminal state when switching projects (#358) by @Andy in 7881b2d1
|
||||
- fix(analyzer): add C#/Java/Swift/Kotlin project files to security hash (#351) by @Michael Ludlow in 4e71361b
|
||||
- fix: make backend tests pass on Windows (#282) by @Oluwatosin Oyeladun in 4dcc5afa
|
||||
- fix(ui): close parent modal when Edit dialog opens (#354) by @Michael Ludlow in e9782db0
|
||||
- chore: bump version to 2.7.2-beta.10 by @AndyMik90 in 40d04d7c
|
||||
- feat: add terminal dropdown with inbuilt and external options in task review (#347) by @JoshuaRileyDev in fef07c95
|
||||
- refactor: remove deprecated code across backend and frontend (#348) by @Mitsu in 9d43abed
|
||||
- feat: centralize CLI tool path management (#341) by @HSSAINI Saad in d51f4562
|
||||
- refactor(components): remove deprecated TaskDetailPanel re-export (#344) by @Mitsu in 787667e9
|
||||
- chore: Refactor/kanban realtime status sync (#249) by @souky-byte in 9734b70b
|
||||
- refactor(settings): remove deprecated ProjectSettings modal and hooks (#343) by @Mitsu in fec6b9f3
|
||||
- perf: convert synchronous I/O to async operations in worktree handlers (#337) by @JoshuaRileyDev in d3a63b09
|
||||
- feat: bump version (#329) by @Alex in 50e3111a
|
||||
- fix(ci): remove version bump to fix branch protection conflict (#325) by @Michael Ludlow in 8a80b1d5
|
||||
- fix(tasks): sync status to worktree implementation plan to prevent reset (#243) (#323) by @Alex in cb6b2165
|
||||
- fix(ci): add auto-updater manifest files and version auto-update (#317) by @Michael Ludlow in 661e47c3
|
||||
- fix(project): fix task status persistence reverting on refresh (#246) (#318) by @Michael Ludlow in e80ef79d
|
||||
- fix(updater): proper semver comparison for pre-release versions (#313) by @Michael Ludlow in e1b0f743
|
||||
- fix(python): use venv Python for all services to fix dotenv errors (#311) by @Alex in 92c6f278
|
||||
- chore(ci): cancel in-progress runs (#302) by @Oluwatosin Oyeladun in 1c142273
|
||||
- fix(build): use explicit Windows System32 tar path (#308) by @Andy in c0a02a45
|
||||
- fix(github): add augmented PATH env to all gh CLI calls by @AndyMik90 in 086429cb
|
||||
- fix(build): use PowerShell for tar extraction on Windows by @AndyMik90 in d9fb8f29
|
||||
- fix(build): add --force-local flag to tar on Windows (#303) by @Andy in d0b0b3df
|
||||
- fix: stop tracking spec files in git (#295) by @Andy in 937a60f8
|
||||
- Fix/2.7.2 fixes (#300) by @Andy in 7a51cbd5
|
||||
- feat(merge,oauth): add path-aware AI merge resolution and device code streaming (#296) by @Andy in 26beefe3
|
||||
- feat: enhance the logs for the commit linting stage (#293) by @Alex in 8416f307
|
||||
- fix(github): add explicit GET method to gh api comment fetches (#294) by @Andy in 217249c8
|
||||
- fix(frontend): support archiving tasks across all worktree locations (#286) by @Andy in 8bb3df91
|
||||
- Potential fix for code scanning alert no. 224: Uncontrolled command line (#285) by @Andy in 5106c6e9
|
||||
- fix(frontend): validate backend source path before using it (#287) by @Andy in 3ff61274
|
||||
- feat(python): bundle Python 3.12 with packaged Electron app (#284) by @Andy in 7f19c2e1
|
||||
- fix: resolve spawn python ENOENT error on Linux by using getAugmentedEnv() (#281) by @Todd W. Bucy in d98e2830
|
||||
- fix(ci): add write permissions to beta-release update-version job by @AndyMik90 in 0b874d4b
|
||||
- chore(deps): bump @xterm/xterm from 5.5.0 to 6.0.0 in /apps/frontend (#270) by @dependabot[bot] in 50dd1078
|
||||
- fix(github): resolve follow-up review API issues by @AndyMik90 in f1cc5a09
|
||||
- fix(security): resolve CodeQL file system race conditions and unused variables (#277) by @Andy in b005fa5c
|
||||
- fix(ci): use correct electron-builder arch flags (#278) by @Andy in d79f2da4
|
||||
- chore(deps): bump jsdom from 26.1.0 to 27.3.0 in /apps/frontend (#268) by @dependabot[bot] in 5ac566e2
|
||||
- chore(deps): bump typescript-eslint in /apps/frontend (#269) by @dependabot[bot] in f49d4817
|
||||
- fix(ci): use develop branch for dry-run builds in beta-release workflow (#276) by @Andy in 1e1d7d9b
|
||||
- fix: accept bug_fix workflow_type alias during planning (#240) by @Daniel Frey in e74a3dff
|
||||
- fix(paths): normalize relative paths to posix (#239) by @Daniel Frey in 6ac8250b
|
||||
- chore(deps): bump @electron/rebuild in /apps/frontend (#271) by @dependabot[bot] in a2cee694
|
||||
- chore(deps): bump vitest from 4.0.15 to 4.0.16 in /apps/frontend (#272) by @dependabot[bot] in d4cad80a
|
||||
- feat(github): add automated PR review with follow-up support (#252) by @Andy in 596e9513
|
||||
- ci: implement enterprise-grade PR quality gates and security scanning (#266) by @Alex in d42041c5
|
||||
- fix: update path resolution for ollama_model_detector.py in memory handlers (#263) by @delyethan in a3f87540
|
||||
- feat: add i18n internationalization system (#248) by @Mitsu in f8438112
|
||||
- Revert "Feat/Auto Fix Github issues and do extensive AI PR reviews (#250)" (#251) by @Andy in 5e8c5308
|
||||
- Feat/Auto Fix Github issues and do extensive AI PR reviews (#250) by @Andy in 348de6df
|
||||
- fix: resolve Python detection and backend packaging issues (#241) by @HSSAINI Saad in 0f7d6e05
|
||||
- fix: add future annotations import to discovery.py (#229) by @Joris Slagter in 5ccdb6ab
|
||||
- Fix/ideation status sync (#212) by @souky-byte in 6ec8549f
|
||||
- fix(core): add global spec numbering lock to prevent collisions (#209) by @Andy in 53527293
|
||||
- feat: Add OpenRouter as LLM/embedding provider (#162) by @Fernando Possebon in 02bef954
|
||||
- fix: Add Python 3.10+ version validation and GitHub Actions Python setup (#180 #167) (#208) by @Fernando Possebon in f168bdc3
|
||||
- fix(ci): correct welcome workflow PR message (#206) by @Andy in e3eec68a
|
||||
- Feat/beta release (#193) by @Andy in 407a0bee
|
||||
- feat/beta-release (#190) by @Andy in 8f766ad1
|
||||
- fix/PRs from old main setup to apps structure (#185) by @Andy in ced2ad47
|
||||
- fix: hide status badge when execution phase badge is showing (#154) by @Andy in 05f5d303
|
||||
- feat: Add UI scale feature with 75-200% range (#125) by @Enes Cingöz in 6951251b
|
||||
- fix(task): stop running process when task status changes away from in_progress by @AndyMik90 in 30e7536b
|
||||
- Fix/linear 400 error by @Andy in 220faf0f
|
||||
- fix: remove legacy path from auto-claude source detection (#148) by @Joris Slagter in f96c6301
|
||||
- fix: resolve Python environment race condition (#142) by @Joris Slagter in ebd8340d
|
||||
- Feat: Ollama download progress tracking with new apps structure (#141) by @rayBlock in df779530
|
||||
- Feature/apps restructure v2.7.2 (#138) by @Andy in 0adaddac
|
||||
- docs: Add Git Flow branching strategy to CONTRIBUTING.md by @AndyMik90 in 91f7051d
|
||||
|
||||
## Thanks to all contributors
|
||||
|
||||
@Andy, @Adryan Serage, @Michael Ludlow, @Navid, @Mulaveesala Pranaveswar, @Vinícius Santos, @Abe Diaz, @Mitsu, @Alex, @AndyMik90, @Joe, @Illia Filippov, @Ian, @Brian, @Kevin Rajan, @Oluwatosin Oyeladun, @JoshuaRileyDev, @HSSAINI Saad, @souky-byte, @Todd W. Bucy, @dependabot[bot], @Daniel Frey, @delyethan, @Joris Slagter, @Fernando Possebon, @Enes Cingöz, @rayBlock
|
||||
|
||||
## 2.7.1 - Build Pipeline Enhancements
|
||||
|
||||
### 🛠️ Improvements
|
||||
|
||||
+90
-23
@@ -69,9 +69,38 @@ This will:
|
||||
- Update `apps/frontend/package.json`
|
||||
- Update `package.json` (root)
|
||||
- Update `apps/backend/__init__.py`
|
||||
- Check if `CHANGELOG.md` has an entry for the new version (warns if missing)
|
||||
- Create a commit with message `chore: bump version to X.Y.Z`
|
||||
|
||||
### Step 2: Push and Create PR
|
||||
### Step 2: Update CHANGELOG.md (REQUIRED)
|
||||
|
||||
**IMPORTANT: The release will fail if CHANGELOG.md doesn't have an entry for the new version.**
|
||||
|
||||
Add release notes to `CHANGELOG.md` at the top of the file:
|
||||
|
||||
```markdown
|
||||
## 2.8.0 - Your Release Title
|
||||
|
||||
### ✨ New Features
|
||||
- Feature description
|
||||
|
||||
### 🛠️ Improvements
|
||||
- Improvement description
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
- Fix description
|
||||
|
||||
---
|
||||
```
|
||||
|
||||
Then amend the version bump commit:
|
||||
|
||||
```bash
|
||||
git add CHANGELOG.md
|
||||
git commit --amend --no-edit
|
||||
```
|
||||
|
||||
### Step 3: Push and Create PR
|
||||
|
||||
```bash
|
||||
# Push your branch
|
||||
@@ -81,24 +110,25 @@ git push origin your-branch
|
||||
gh pr create --base main --title "Release v2.8.0"
|
||||
```
|
||||
|
||||
### Step 3: Merge to Main
|
||||
### Step 4: Merge to Main
|
||||
|
||||
Once the PR is approved and merged to `main`, GitHub Actions will automatically:
|
||||
|
||||
1. **Detect the version bump** (`prepare-release.yml`)
|
||||
2. **Create a git tag** (e.g., `v2.8.0`)
|
||||
3. **Trigger the release workflow** (`release.yml`)
|
||||
4. **Build binaries** for all platforms:
|
||||
2. **Validate CHANGELOG.md** has an entry for the new version (FAILS if missing)
|
||||
3. **Extract release notes** from CHANGELOG.md
|
||||
4. **Create a git tag** (e.g., `v2.8.0`)
|
||||
5. **Trigger the release workflow** (`release.yml`)
|
||||
6. **Build binaries** for all platforms:
|
||||
- macOS Intel (x64) - code signed & notarized
|
||||
- macOS Apple Silicon (arm64) - code signed & notarized
|
||||
- Windows (NSIS installer) - code signed
|
||||
- Linux (AppImage + .deb)
|
||||
5. **Generate changelog** from merged PRs (using release-drafter)
|
||||
6. **Scan binaries** with VirusTotal
|
||||
7. **Create GitHub release** with all artifacts
|
||||
8. **Update README** with new version badge and download links
|
||||
7. **Scan binaries** with VirusTotal
|
||||
8. **Create GitHub release** with release notes from CHANGELOG.md
|
||||
9. **Update README** with new version badge and download links
|
||||
|
||||
### Step 4: Verify
|
||||
### Step 5: Verify
|
||||
|
||||
After merging, check:
|
||||
- [GitHub Actions](https://github.com/AndyMik90/Auto-Claude/actions) - ensure all workflows pass
|
||||
@@ -113,28 +143,49 @@ We follow [Semantic Versioning](https://semver.org/):
|
||||
- **MINOR** (0.X.0): New features, backwards compatible
|
||||
- **PATCH** (0.0.X): Bug fixes, backwards compatible
|
||||
|
||||
## Changelog Generation
|
||||
## Changelog Management
|
||||
|
||||
Changelogs are automatically generated from merged PRs using [Release Drafter](https://github.com/release-drafter/release-drafter).
|
||||
Release notes are managed in `CHANGELOG.md` and used for GitHub releases.
|
||||
|
||||
### PR Labels for Changelog Categories
|
||||
### Changelog Format
|
||||
|
||||
| Label | Category |
|
||||
|-------|----------|
|
||||
| `feature`, `enhancement` | New Features |
|
||||
| `bug`, `fix` | Bug Fixes |
|
||||
| `improvement`, `refactor` | Improvements |
|
||||
| `documentation` | Documentation |
|
||||
| (any other) | Other Changes |
|
||||
Each version entry in `CHANGELOG.md` should follow this format:
|
||||
|
||||
**Tip:** Add appropriate labels to your PRs for better changelog organization.
|
||||
```markdown
|
||||
## X.Y.Z - Release Title
|
||||
|
||||
### ✨ New Features
|
||||
- Feature description with context
|
||||
|
||||
### 🛠️ Improvements
|
||||
- Improvement description
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
- Fix description
|
||||
|
||||
---
|
||||
```
|
||||
|
||||
### Changelog Validation
|
||||
|
||||
The release workflow **validates** that `CHANGELOG.md` has an entry for the version being released:
|
||||
|
||||
- If the entry is **missing**, the release is **blocked** with a clear error message
|
||||
- If the entry **exists**, its content is used for the GitHub release notes
|
||||
|
||||
### Writing Good Release Notes
|
||||
|
||||
- **Be specific**: Instead of "Fixed bug", write "Fixed crash when opening large files"
|
||||
- **Group by impact**: Features first, then improvements, then fixes
|
||||
- **Credit contributors**: Mention contributors for significant changes
|
||||
- **Link issues**: Reference GitHub issues where relevant (e.g., "Fixes #123")
|
||||
|
||||
## Workflows
|
||||
|
||||
| Workflow | Trigger | Purpose |
|
||||
|----------|---------|---------|
|
||||
| `prepare-release.yml` | Push to `main` | Detects version bump, creates tag |
|
||||
| `release.yml` | Tag `v*` pushed | Builds binaries, creates release |
|
||||
| `prepare-release.yml` | Push to `main` | Detects version bump, **validates CHANGELOG.md**, creates tag |
|
||||
| `release.yml` | Tag `v*` pushed | Builds binaries, extracts changelog, creates release |
|
||||
| `validate-version.yml` | Tag `v*` pushed | Validates tag matches package.json |
|
||||
| `update-readme` (in release.yml) | After release | Updates README with new version |
|
||||
|
||||
@@ -153,6 +204,22 @@ Changelogs are automatically generated from merged PRs using [Release Drafter](h
|
||||
git diff HEAD~1 --name-only | grep package.json
|
||||
```
|
||||
|
||||
### Release blocked: Missing changelog entry
|
||||
|
||||
If you see "CHANGELOG VALIDATION FAILED" in the workflow:
|
||||
|
||||
1. The `prepare-release.yml` workflow validated that `CHANGELOG.md` doesn't have an entry for the new version
|
||||
2. **Fix**: Add an entry to `CHANGELOG.md` with the format `## X.Y.Z - Title`
|
||||
3. Commit and push the changelog update
|
||||
4. The workflow will automatically retry when the changes are pushed to `main`
|
||||
|
||||
```bash
|
||||
# Add changelog entry, then:
|
||||
git add CHANGELOG.md
|
||||
git commit -m "docs: add changelog for vX.Y.Z"
|
||||
git push origin main
|
||||
```
|
||||
|
||||
### Build failed after tag was created
|
||||
|
||||
- The release won't be published if builds fail
|
||||
|
||||
@@ -45,7 +45,8 @@ def apply_single_task_changes(
|
||||
# Addition - need to determine where to add
|
||||
if change.change_type == ChangeType.ADD_IMPORT:
|
||||
# Add import at top
|
||||
lines = content.split("\n")
|
||||
# Use splitlines() to handle all line ending styles (LF, CRLF, CR)
|
||||
lines = content.splitlines()
|
||||
import_end = find_import_end(lines, file_path)
|
||||
lines.insert(import_end, change.content_after)
|
||||
content = "\n".join(lines)
|
||||
@@ -96,7 +97,8 @@ def combine_non_conflicting_changes(
|
||||
|
||||
# Add imports
|
||||
if imports:
|
||||
lines = content.split("\n")
|
||||
# Use splitlines() to handle all line ending styles (LF, CRLF, CR)
|
||||
lines = content.splitlines()
|
||||
import_end = find_import_end(lines, file_path)
|
||||
for imp in imports:
|
||||
if imp.content_after and imp.content_after not in content:
|
||||
|
||||
@@ -30,11 +30,16 @@ def analyze_with_regex(
|
||||
"""
|
||||
changes: list[SemanticChange] = []
|
||||
|
||||
# Normalize line endings to LF for consistent cross-platform behavior
|
||||
# This handles Windows CRLF, old Mac CR, and Unix LF
|
||||
before_normalized = before.replace("\r\n", "\n").replace("\r", "\n")
|
||||
after_normalized = after.replace("\r\n", "\n").replace("\r", "\n")
|
||||
|
||||
# Get a unified diff
|
||||
diff = list(
|
||||
difflib.unified_diff(
|
||||
before.splitlines(keepends=True),
|
||||
after.splitlines(keepends=True),
|
||||
before_normalized.splitlines(keepends=True),
|
||||
after_normalized.splitlines(keepends=True),
|
||||
lineterm="",
|
||||
)
|
||||
)
|
||||
@@ -89,8 +94,22 @@ def analyze_with_regex(
|
||||
# Detect function changes (simplified)
|
||||
func_pattern = get_function_pattern(ext)
|
||||
if func_pattern:
|
||||
funcs_before = set(func_pattern.findall(before))
|
||||
funcs_after = set(func_pattern.findall(after))
|
||||
# For JS/TS patterns with alternation, findall() returns tuples
|
||||
# Extract the non-empty match from each tuple
|
||||
def extract_func_names(matches):
|
||||
names = set()
|
||||
for match in matches:
|
||||
if isinstance(match, tuple):
|
||||
# Get the first non-empty group from the tuple
|
||||
name = next((m for m in match if m), None)
|
||||
if name:
|
||||
names.add(name)
|
||||
elif match:
|
||||
names.add(match)
|
||||
return names
|
||||
|
||||
funcs_before = extract_func_names(func_pattern.findall(before_normalized))
|
||||
funcs_after = extract_func_names(func_pattern.findall(after_normalized))
|
||||
|
||||
for func in funcs_after - funcs_before:
|
||||
changes.append(
|
||||
|
||||
@@ -211,12 +211,18 @@ class SemanticAnalyzer:
|
||||
"""Analyze using tree-sitter AST parsing."""
|
||||
parser = self._parsers[ext]
|
||||
|
||||
tree_before = parser.parse(bytes(before, "utf-8"))
|
||||
tree_after = parser.parse(bytes(after, "utf-8"))
|
||||
# Normalize line endings to LF for consistent cross-platform behavior
|
||||
# This ensures byte positions and line counts work correctly on all platforms
|
||||
before_normalized = before.replace("\r\n", "\n").replace("\r", "\n")
|
||||
after_normalized = after.replace("\r\n", "\n").replace("\r", "\n")
|
||||
|
||||
tree_before = parser.parse(bytes(before_normalized, "utf-8"))
|
||||
tree_after = parser.parse(bytes(after_normalized, "utf-8"))
|
||||
|
||||
# Extract structural elements from both versions
|
||||
elements_before = self._extract_elements(tree_before, before, ext)
|
||||
elements_after = self._extract_elements(tree_after, after, ext)
|
||||
# Use normalized content to match tree-sitter byte positions
|
||||
elements_before = self._extract_elements(tree_before, before_normalized, ext)
|
||||
elements_after = self._extract_elements(tree_after, after_normalized, ext)
|
||||
|
||||
# Compare and generate semantic changes
|
||||
changes = compare_elements(elements_before, elements_after, ext)
|
||||
|
||||
@@ -609,12 +609,12 @@ function installPackages(pythonBin, requirementsPath, targetSitePackages) {
|
||||
|
||||
// Install packages directly to target directory
|
||||
// --no-compile: Don't create .pyc files (saves space, Python will work without them)
|
||||
// --no-cache-dir: Don't use pip cache
|
||||
// --target: Install to specific directory
|
||||
// Note: We intentionally DO use pip's cache to preserve built wheels for packages
|
||||
// like real_ladybug that must be compiled from source on Intel Mac (no PyPI wheel)
|
||||
const pipArgs = [
|
||||
'-m', 'pip', 'install',
|
||||
'--no-compile',
|
||||
'--no-cache-dir',
|
||||
'--target', targetSitePackages,
|
||||
'-r', requirementsPath,
|
||||
];
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { app, BrowserWindow, shell, nativeImage } from 'electron';
|
||||
import { app, BrowserWindow, shell, nativeImage, session } from 'electron';
|
||||
import { join } from 'path';
|
||||
import { accessSync, readFileSync, writeFileSync } from 'fs';
|
||||
import { electronApp, optimizer, is } from '@electron-toolkit/utils';
|
||||
@@ -110,11 +110,25 @@ if (process.platform === 'darwin') {
|
||||
app.name = 'Auto Claude';
|
||||
}
|
||||
|
||||
// Fix Windows GPU cache permission errors (0x5 Access Denied)
|
||||
if (process.platform === 'win32') {
|
||||
app.commandLine.appendSwitch('disable-gpu-shader-disk-cache');
|
||||
app.commandLine.appendSwitch('disable-gpu-program-cache');
|
||||
console.log('[main] Applied Windows GPU cache fixes');
|
||||
}
|
||||
|
||||
// Initialize the application
|
||||
app.whenReady().then(() => {
|
||||
// Set app user model id for Windows
|
||||
electronApp.setAppUserModelId('com.autoclaude.ui');
|
||||
|
||||
// Clear cache on Windows to prevent permission errors from stale cache
|
||||
if (process.platform === 'win32') {
|
||||
session.defaultSession.clearCache()
|
||||
.then(() => console.log('[main] Cleared cache on startup'))
|
||||
.catch((err) => console.warn('[main] Failed to clear cache:', err));
|
||||
}
|
||||
|
||||
// Set dock icon on macOS
|
||||
if (process.platform === 'darwin') {
|
||||
const iconPath = getIconPath();
|
||||
|
||||
@@ -5,9 +5,65 @@
|
||||
|
||||
import * as pty from '@lydell/node-pty';
|
||||
import * as os from 'os';
|
||||
import { existsSync } from 'fs';
|
||||
import type { TerminalProcess, WindowGetter } from './types';
|
||||
import { IPC_CHANNELS } from '../../shared/constants';
|
||||
import { getClaudeProfileManager } from '../claude-profile-manager';
|
||||
import { readSettingsFile } from '../settings-utils';
|
||||
import type { SupportedTerminal } from '../../shared/types/settings';
|
||||
|
||||
/**
|
||||
* Windows shell paths for different terminal preferences
|
||||
*/
|
||||
const WINDOWS_SHELL_PATHS: Record<string, string[]> = {
|
||||
powershell: [
|
||||
'C:\\Program Files\\PowerShell\\7\\pwsh.exe', // PowerShell 7 (Core)
|
||||
'C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe', // Windows PowerShell 5.1
|
||||
],
|
||||
windowsterminal: [
|
||||
'C:\\Program Files\\PowerShell\\7\\pwsh.exe', // Prefer PowerShell Core in Windows Terminal
|
||||
'C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe',
|
||||
],
|
||||
cmd: [
|
||||
'C:\\Windows\\System32\\cmd.exe',
|
||||
],
|
||||
gitbash: [
|
||||
'C:\\Program Files\\Git\\bin\\bash.exe',
|
||||
'C:\\Program Files (x86)\\Git\\bin\\bash.exe',
|
||||
],
|
||||
cygwin: [
|
||||
'C:\\cygwin64\\bin\\bash.exe',
|
||||
'C:\\cygwin\\bin\\bash.exe',
|
||||
],
|
||||
msys2: [
|
||||
'C:\\msys64\\usr\\bin\\bash.exe',
|
||||
'C:\\msys32\\usr\\bin\\bash.exe',
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the Windows shell executable based on preferred terminal setting
|
||||
*/
|
||||
function getWindowsShell(preferredTerminal: SupportedTerminal | undefined): string {
|
||||
// If no preference or 'system', use COMSPEC (usually cmd.exe)
|
||||
if (!preferredTerminal || preferredTerminal === 'system') {
|
||||
return process.env.COMSPEC || 'cmd.exe';
|
||||
}
|
||||
|
||||
// Check if we have paths defined for this terminal type
|
||||
const paths = WINDOWS_SHELL_PATHS[preferredTerminal];
|
||||
if (paths) {
|
||||
// Find the first existing shell
|
||||
for (const shellPath of paths) {
|
||||
if (existsSync(shellPath)) {
|
||||
return shellPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to COMSPEC for unrecognized terminals
|
||||
return process.env.COMSPEC || 'cmd.exe';
|
||||
}
|
||||
|
||||
/**
|
||||
* Spawn a new PTY process with appropriate shell and environment
|
||||
@@ -18,13 +74,17 @@ export function spawnPtyProcess(
|
||||
rows: number,
|
||||
profileEnv?: Record<string, string>
|
||||
): pty.IPty {
|
||||
// Read user's preferred terminal setting
|
||||
const settings = readSettingsFile();
|
||||
const preferredTerminal = settings?.preferredTerminal as SupportedTerminal | undefined;
|
||||
|
||||
const shell = process.platform === 'win32'
|
||||
? process.env.COMSPEC || 'cmd.exe'
|
||||
? getWindowsShell(preferredTerminal)
|
||||
: process.env.SHELL || '/bin/zsh';
|
||||
|
||||
const shellArgs = process.platform === 'win32' ? [] : ['-l'];
|
||||
|
||||
console.warn('[PtyManager] Spawning shell:', shell, shellArgs);
|
||||
console.warn('[PtyManager] Spawning shell:', shell, shellArgs, '(preferred:', preferredTerminal || 'system', ')');
|
||||
|
||||
return pty.spawn(shell, shellArgs, {
|
||||
name: 'xterm-256color',
|
||||
|
||||
+66
-7
@@ -149,6 +149,27 @@ function updateBackendInit(newVersion) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if CHANGELOG.md has an entry for the version
|
||||
function checkChangelogEntry(version) {
|
||||
const changelogPath = path.join(__dirname, '..', 'CHANGELOG.md');
|
||||
|
||||
if (!fs.existsSync(changelogPath)) {
|
||||
warning('CHANGELOG.md not found - you will need to create it before releasing');
|
||||
return false;
|
||||
}
|
||||
|
||||
const content = fs.readFileSync(changelogPath, 'utf8');
|
||||
|
||||
// Look for "## X.Y.Z" or "## X.Y.Z -" header
|
||||
const versionPattern = new RegExp(`^## ${version.replace(/\./g, '\\.')}(\\s|-)`, 'm');
|
||||
|
||||
if (versionPattern.test(content)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Main function
|
||||
function main() {
|
||||
const bumpType = process.argv[2];
|
||||
@@ -198,7 +219,35 @@ function main() {
|
||||
// after the GitHub release is successfully published. This prevents version
|
||||
// mismatches where README shows a version that doesn't exist yet.
|
||||
|
||||
// 6. Create git commit
|
||||
// 6. Check if CHANGELOG.md has entry for this version
|
||||
info('Checking CHANGELOG.md...');
|
||||
const hasChangelogEntry = checkChangelogEntry(newVersion);
|
||||
|
||||
if (hasChangelogEntry) {
|
||||
success(`CHANGELOG.md already has entry for ${newVersion}`);
|
||||
} else {
|
||||
log('');
|
||||
warning('═══════════════════════════════════════════════════════════════════════');
|
||||
warning(' CHANGELOG.md does not have an entry for version ' + newVersion);
|
||||
warning('═══════════════════════════════════════════════════════════════════════');
|
||||
warning('');
|
||||
warning(' The release workflow will FAIL if CHANGELOG.md is not updated!');
|
||||
warning('');
|
||||
warning(' Please add an entry to CHANGELOG.md before creating your PR:');
|
||||
warning('');
|
||||
log(` ## ${newVersion} - Your Release Title`, colors.cyan);
|
||||
log('', colors.cyan);
|
||||
log(' ### ✨ New Features', colors.cyan);
|
||||
log(' - Feature description', colors.cyan);
|
||||
log('', colors.cyan);
|
||||
log(' ### 🐛 Bug Fixes', colors.cyan);
|
||||
log(' - Fix description', colors.cyan);
|
||||
warning('');
|
||||
warning('═══════════════════════════════════════════════════════════════════════');
|
||||
log('');
|
||||
}
|
||||
|
||||
// 7. Create git commit
|
||||
info('Creating git commit...');
|
||||
exec('git add apps/frontend/package.json package.json apps/backend/__init__.py');
|
||||
exec(`git commit -m "chore: bump version to ${newVersion}"`);
|
||||
@@ -208,18 +257,28 @@ function main() {
|
||||
// when this commit is merged to main, ensuring releases only happen after
|
||||
// successful builds.
|
||||
|
||||
// 7. Instructions
|
||||
// 8. Instructions
|
||||
log('\n📋 Next steps:', colors.yellow);
|
||||
log(` 1. Review the changes: git log -1`, colors.yellow);
|
||||
log(` 2. Push to your branch: git push origin <branch-name>`, colors.yellow);
|
||||
log(` 3. Create PR to main (or merge develop → main)`, colors.yellow);
|
||||
log(` 4. When merged, GitHub Actions will automatically:`, colors.yellow);
|
||||
if (!hasChangelogEntry) {
|
||||
log(` 1. UPDATE CHANGELOG.md with release notes for ${newVersion}`, colors.red);
|
||||
log(` 2. Commit the changelog: git add CHANGELOG.md && git commit --amend --no-edit`, colors.yellow);
|
||||
log(` 3. Push to your branch: git push origin <branch-name>`, colors.yellow);
|
||||
} else {
|
||||
log(` 1. Review the changes: git log -1`, colors.yellow);
|
||||
log(` 2. Push to your branch: git push origin <branch-name>`, colors.yellow);
|
||||
}
|
||||
log(` ${hasChangelogEntry ? '3' : '4'}. Create PR to main (or merge develop → main)`, colors.yellow);
|
||||
log(` ${hasChangelogEntry ? '4' : '5'}. When merged, GitHub Actions will automatically:`, colors.yellow);
|
||||
log(` - Validate CHANGELOG.md has entry for v${newVersion}`, colors.yellow);
|
||||
log(` - Create tag v${newVersion}`, colors.yellow);
|
||||
log(` - Build binaries for all platforms`, colors.yellow);
|
||||
log(` - Create GitHub release with changelog`, colors.yellow);
|
||||
log(` - Create GitHub release with changelog from CHANGELOG.md`, colors.yellow);
|
||||
log(` - Update README with new version\n`, colors.yellow);
|
||||
|
||||
warning('Note: The commit has been created locally but NOT pushed.');
|
||||
if (!hasChangelogEntry) {
|
||||
warning('IMPORTANT: Update CHANGELOG.md before pushing or the release will fail!');
|
||||
}
|
||||
info('Tags are created automatically by GitHub Actions when merged to main.');
|
||||
|
||||
log('\n✨ Version bump complete!\n', colors.green);
|
||||
|
||||
Reference in New Issue
Block a user