feat/beta-release (#190)
* chore: update README version to 2.7.1 Updated the version badge and download links in the README to reflect the new release version 2.7.1, ensuring users have the correct information for downloading the latest builds. * feat(releases): add beta release system with user opt-in Implements a complete beta release workflow that allows users to opt-in to receiving pre-release versions. This enables testing new features before they're included in stable releases. Changes: - Add beta-release.yml workflow for creating beta releases from develop - Add betaUpdates setting with UI toggle in Settings > Updates - Add update channel support to electron-updater (beta vs latest) - Extract shared settings-utils.ts to reduce code duplication - Add prepare-release.yml workflow for automated release preparation - Document beta release process in CONTRIBUTING.md and RELEASE.md Users can enable beta updates in Settings > Updates, and maintainers can trigger beta releases via the GitHub Actions workflow. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * workflow update --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,75 +1,27 @@
|
||||
name: Bug Report
|
||||
description: Report a bug or unexpected behavior
|
||||
labels: ["bug", "triage"]
|
||||
name: 🐛 Bug Report
|
||||
description: Something isn't working
|
||||
labels: ["bug", "needs-triage"]
|
||||
body:
|
||||
- type: markdown
|
||||
- type: checkboxes
|
||||
id: checklist
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to report a bug! Please fill out the sections below.
|
||||
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Bug Description
|
||||
description: A clear and concise description of the bug.
|
||||
placeholder: What happened?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: expected
|
||||
attributes:
|
||||
label: Expected Behavior
|
||||
description: What did you expect to happen?
|
||||
placeholder: What should have happened?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: reproduce
|
||||
attributes:
|
||||
label: Steps to Reproduce
|
||||
description: Steps to reproduce the behavior.
|
||||
placeholder: |
|
||||
1. Run command '...'
|
||||
2. Click on '...'
|
||||
3. See error
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Error Messages / Logs
|
||||
description: If applicable, paste any error messages or logs.
|
||||
render: shell
|
||||
|
||||
- type: textarea
|
||||
id: screenshots
|
||||
attributes:
|
||||
label: Screenshots
|
||||
description: If applicable, add screenshots to help explain the problem.
|
||||
label: Checklist
|
||||
options:
|
||||
- label: I searched existing issues and this hasn't been reported
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: component
|
||||
id: area
|
||||
attributes:
|
||||
label: Component
|
||||
description: Which part of Auto Claude is affected?
|
||||
label: Area
|
||||
options:
|
||||
- Python Backend (apps/backend/)
|
||||
- Electron UI (apps/frontend/)
|
||||
- Both
|
||||
- Frontend
|
||||
- Backend
|
||||
- Fullstack
|
||||
- Not sure
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Auto Claude Version
|
||||
description: What version are you running? (check package.json or git tag)
|
||||
placeholder: "v2.0.1"
|
||||
|
||||
- type: dropdown
|
||||
id: os
|
||||
attributes:
|
||||
@@ -78,26 +30,47 @@ body:
|
||||
- macOS
|
||||
- Windows
|
||||
- Linux
|
||||
- Other
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: python-version
|
||||
id: version
|
||||
attributes:
|
||||
label: Python Version
|
||||
description: Output of `python --version`
|
||||
placeholder: "3.12.0"
|
||||
|
||||
- type: input
|
||||
id: node-version
|
||||
attributes:
|
||||
label: Node.js Version (for UI issues)
|
||||
description: Output of `node --version`
|
||||
placeholder: "20.10.0"
|
||||
label: Version
|
||||
placeholder: "e.g., 2.5.5"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: additional
|
||||
id: description
|
||||
attributes:
|
||||
label: Additional Context
|
||||
description: Any other context about the problem.
|
||||
label: What happened?
|
||||
placeholder: Describe the bug clearly and concisely. Include any error messages you encountered.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: steps
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
placeholder: |
|
||||
1. Run command '...' or click on '...'
|
||||
2. Observe behavior '...'
|
||||
3. See error or unexpected result
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: expected
|
||||
attributes:
|
||||
label: Expected behavior
|
||||
placeholder: What did you expect to happen instead? Describe the correct behavior.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Logs / Screenshots
|
||||
description: Required for UI bugs. Attach relevant logs, screenshots, or error output.
|
||||
render: shell
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Questions & Discussions
|
||||
url: https://github.com/AndyMik90/Auto-Claude/discussions
|
||||
about: Ask questions and discuss ideas with the community
|
||||
- name: Documentation
|
||||
url: https://github.com/AndyMik90/Auto-Claude#readme
|
||||
about: Check the documentation before opening an issue
|
||||
- name: 💡 Feature Request
|
||||
url: https://github.com/AndyMik90/Auto-Claude/discussions/new?category=ideas
|
||||
about: Suggest new features in GitHub Discussions
|
||||
- name: 💬 Discord Community
|
||||
url: https://discord.gg/KCXaPBr4Dj
|
||||
about: Questions and discussions - join our Discord!
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
name: 📚 Documentation
|
||||
description: Improvements or additions to documentation
|
||||
labels: ["documentation", "needs-triage", "help wanted"]
|
||||
body:
|
||||
- type: dropdown
|
||||
id: type
|
||||
attributes:
|
||||
label: Type
|
||||
options:
|
||||
- Missing documentation
|
||||
- Incorrect/outdated info
|
||||
- Improvement suggestion
|
||||
- Typo/grammar fix
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: location
|
||||
attributes:
|
||||
label: Location
|
||||
description: Which file or page?
|
||||
placeholder: "e.g., README.md or guides/setup.md"
|
||||
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description
|
||||
description: What needs to change?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: checkboxes
|
||||
id: contribute
|
||||
attributes:
|
||||
label: Contribution
|
||||
options:
|
||||
- label: I'm willing to submit a PR for this
|
||||
@@ -1,70 +0,0 @@
|
||||
name: Feature Request
|
||||
description: Suggest a new feature or enhancement
|
||||
labels: ["enhancement", "triage"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for suggesting a feature! Please describe your idea below.
|
||||
|
||||
- type: textarea
|
||||
id: problem
|
||||
attributes:
|
||||
label: Problem Statement
|
||||
description: What problem does this feature solve? Is this related to a frustration?
|
||||
placeholder: I'm always frustrated when...
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: solution
|
||||
attributes:
|
||||
label: Proposed Solution
|
||||
description: Describe the solution you'd like to see.
|
||||
placeholder: I would like Auto Claude to...
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: alternatives
|
||||
attributes:
|
||||
label: Alternatives Considered
|
||||
description: Have you considered any alternative solutions or workarounds?
|
||||
placeholder: I've tried...
|
||||
|
||||
- type: dropdown
|
||||
id: component
|
||||
attributes:
|
||||
label: Component
|
||||
description: Which part of Auto Claude would this affect?
|
||||
options:
|
||||
- Python Backend (apps/backend/)
|
||||
- Electron UI (apps/frontend/)
|
||||
- Both
|
||||
- New component
|
||||
- Not sure
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: priority
|
||||
attributes:
|
||||
label: How important is this feature to you?
|
||||
options:
|
||||
- Nice to have
|
||||
- Important for my workflow
|
||||
- Critical / Blocking my use
|
||||
|
||||
- type: checkboxes
|
||||
id: contribution
|
||||
attributes:
|
||||
label: Contribution
|
||||
description: Would you be willing to help implement this?
|
||||
options:
|
||||
- label: I'm willing to submit a PR for this feature
|
||||
|
||||
- type: textarea
|
||||
id: additional
|
||||
attributes:
|
||||
label: Additional Context
|
||||
description: Add any other context, mockups, or screenshots about the feature request.
|
||||
@@ -0,0 +1,61 @@
|
||||
name: ❓ Question
|
||||
description: Needs clarification
|
||||
labels: ["question", "needs-triage"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
**Before asking:** Check [Discord](https://discord.gg/KCXaPBr4Dj) - your question may already be answered there!
|
||||
|
||||
- type: checkboxes
|
||||
id: checklist
|
||||
attributes:
|
||||
label: Checklist
|
||||
options:
|
||||
- label: I searched existing issues and Discord for similar questions
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: area
|
||||
attributes:
|
||||
label: Area
|
||||
options:
|
||||
- Setup/Installation
|
||||
- Frontend
|
||||
- Backend
|
||||
- Configuration
|
||||
- Other
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
description: Which version are you using?
|
||||
placeholder: "e.g., 2.7.1"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: question
|
||||
attributes:
|
||||
label: Question
|
||||
placeholder: "Describe your question in detail..."
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: context
|
||||
attributes:
|
||||
label: Context
|
||||
description: What are you trying to achieve?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: attempts
|
||||
attributes:
|
||||
label: What have you already tried?
|
||||
description: What steps have you taken to resolve this?
|
||||
placeholder: "e.g., I tried reading the docs, searched for..."
|
||||
@@ -1,44 +1,76 @@
|
||||
## Summary
|
||||
## Base Branch
|
||||
|
||||
<!-- Brief description of what this PR does -->
|
||||
- [ ] This PR targets the `develop` branch (required for all feature/fix PRs)
|
||||
- [ ] This PR targets `main` (hotfix only - maintainers)
|
||||
|
||||
## Description
|
||||
|
||||
<!-- What does this PR do? 2-3 sentences -->
|
||||
|
||||
## Related Issue
|
||||
|
||||
Closes #
|
||||
|
||||
## Type of Change
|
||||
|
||||
- [ ] Bug fix (non-breaking change that fixes an issue)
|
||||
- [ ] New feature (non-breaking change that adds functionality)
|
||||
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
|
||||
- [ ] Documentation update
|
||||
- [ ] Refactoring (no functional changes)
|
||||
- [ ] Tests (adding or updating tests)
|
||||
- [ ] 🐛 Bug fix
|
||||
- [ ] ✨ New feature
|
||||
- [ ] 📚 Documentation
|
||||
- [ ] ♻️ Refactor
|
||||
- [ ] 🧪 Test
|
||||
|
||||
## Related Issues
|
||||
## Area
|
||||
|
||||
<!-- Link any related issues: Fixes #123, Closes #456 -->
|
||||
- [ ] Frontend
|
||||
- [ ] Backend
|
||||
- [ ] Fullstack
|
||||
|
||||
## Changes Made
|
||||
## Commit Message Format
|
||||
|
||||
<!-- List the main changes in this PR -->
|
||||
Follow conventional commits: `<type>: <subject>`
|
||||
|
||||
-
|
||||
-
|
||||
-
|
||||
**Types:** feat, fix, docs, style, refactor, test, chore
|
||||
|
||||
## Screenshots
|
||||
|
||||
<!-- If applicable, add screenshots for UI changes -->
|
||||
**Example:** `feat: add user authentication system`
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] I have run `pre-commit run --all-files` and fixed any issues
|
||||
- [ ] I have added tests for my changes (if applicable)
|
||||
- [ ] All existing tests pass locally
|
||||
- [ ] I have updated documentation (if applicable)
|
||||
- [ ] My code follows the project's code style
|
||||
- [ ] I've synced with `develop` branch
|
||||
- [ ] I've tested my changes locally
|
||||
- [ ] I've followed the code principles (SOLID, DRY, KISS)
|
||||
- [ ] My PR is small and focused (< 400 lines ideally)
|
||||
|
||||
## Testing
|
||||
## CI/Testing Requirements
|
||||
|
||||
<!-- Describe how you tested these changes -->
|
||||
- [ ] All CI checks pass
|
||||
- [ ] All existing tests pass
|
||||
- [ ] New features include test coverage
|
||||
- [ ] Bug fixes include regression tests
|
||||
|
||||
## Additional Notes
|
||||
## Screenshots
|
||||
|
||||
<!-- Any additional context or notes for reviewers -->
|
||||
<!-- Required for UI changes. Delete if not applicable. -->
|
||||
|
||||
| Before | After |
|
||||
|--------|-------|
|
||||
| | |
|
||||
|
||||
## Feature Toggle
|
||||
|
||||
<!-- If feature is incomplete or experimental, how is it hidden from users? -->
|
||||
<!-- This ensures incomplete work can be merged without affecting production. -->
|
||||
|
||||
- [ ] Behind localStorage flag: `use_feature_name`
|
||||
- [ ] Behind settings toggle
|
||||
- [ ] Behind environment variable/config
|
||||
- [ ] N/A - Feature is complete and ready for all users
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
<!-- Does this PR introduce breaking changes? If yes, describe what breaks and migration steps. -->
|
||||
<!-- Delete this section if not applicable. -->
|
||||
|
||||
**Breaking:** Yes / No
|
||||
|
||||
**Details:**
|
||||
<!-- What breaks? What do users/developers need to change? -->
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
name: Auto Label
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
|
||||
jobs:
|
||||
label-area:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
steps:
|
||||
- name: Add area label from form
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const issue = context.payload.issue;
|
||||
const body = issue.body || '';
|
||||
|
||||
console.log(`Processing issue #${issue.number}: ${issue.title}`);
|
||||
|
||||
// Map form selection to label
|
||||
const areaMap = {
|
||||
'Frontend': 'area/frontend',
|
||||
'Backend': 'area/backend',
|
||||
'Fullstack': 'area/fullstack'
|
||||
};
|
||||
|
||||
const labels = [];
|
||||
|
||||
for (const [key, label] of Object.entries(areaMap)) {
|
||||
if (body.includes(key)) {
|
||||
console.log(`Found area: ${key}, adding label: ${label}`);
|
||||
labels.push(label);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (labels.length > 0) {
|
||||
try {
|
||||
await github.rest.issues.addLabels({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: issue.number,
|
||||
labels: labels
|
||||
});
|
||||
console.log(`Successfully added labels: ${labels.join(', ')}`);
|
||||
} catch (error) {
|
||||
core.setFailed(`Failed to add labels: ${error.message}`);
|
||||
}
|
||||
} else {
|
||||
console.log('No matching area found in issue body');
|
||||
}
|
||||
@@ -0,0 +1,389 @@
|
||||
name: Beta Release
|
||||
|
||||
# Manual trigger for beta releases from develop branch
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: 'Beta version (e.g., 2.8.0-beta.1)'
|
||||
required: true
|
||||
type: string
|
||||
dry_run:
|
||||
description: 'Test build without creating release'
|
||||
required: false
|
||||
default: false
|
||||
type: boolean
|
||||
|
||||
jobs:
|
||||
validate-version:
|
||||
name: Validate beta version format
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Validate version format
|
||||
run: |
|
||||
VERSION="${{ github.event.inputs.version }}"
|
||||
|
||||
# Check if version matches beta semver pattern
|
||||
if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+-(beta|alpha|rc)\.[0-9]+$ ]]; then
|
||||
echo "::error::Invalid version format: $VERSION"
|
||||
echo "Version must match pattern: X.Y.Z-beta.N (e.g., 2.8.0-beta.1)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Valid beta version: $VERSION"
|
||||
|
||||
update-version:
|
||||
name: Update package.json version
|
||||
needs: validate-version
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
version: ${{ steps.version.outputs.version }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: develop
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '24'
|
||||
|
||||
- name: Update package.json version
|
||||
id: version
|
||||
run: |
|
||||
VERSION="${{ github.event.inputs.version }}"
|
||||
|
||||
# Update frontend package.json
|
||||
cd apps/frontend
|
||||
npm version "$VERSION" --no-git-tag-version
|
||||
|
||||
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
||||
echo "Updated package.json to version $VERSION"
|
||||
|
||||
- name: Commit version bump
|
||||
if: ${{ github.event.inputs.dry_run != 'true' }}
|
||||
run: |
|
||||
VERSION="${{ github.event.inputs.version }}"
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
# Stage all changed files in frontend directory (handles package-lock.json if it exists)
|
||||
git add -A apps/frontend/
|
||||
git commit -m "chore: bump version to $VERSION for beta release"
|
||||
git push origin develop
|
||||
|
||||
- name: Create and push tag
|
||||
if: ${{ github.event.inputs.dry_run != 'true' }}
|
||||
run: |
|
||||
VERSION="${{ github.event.inputs.version }}"
|
||||
git tag -a "v$VERSION" -m "Beta release v$VERSION"
|
||||
git push origin "v$VERSION"
|
||||
echo "Created tag v$VERSION"
|
||||
|
||||
# Intel build on Intel runner for native compilation
|
||||
build-macos-intel:
|
||||
needs: update-version
|
||||
runs-on: macos-15-intel
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: v${{ needs.update-version.outputs.version }}
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '24'
|
||||
|
||||
- name: Get npm cache directory
|
||||
id: npm-cache
|
||||
run: echo "dir=$(npm config get cache)" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ steps.npm-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
|
||||
restore-keys: ${{ runner.os }}-npm-
|
||||
|
||||
- name: Install dependencies
|
||||
run: cd apps/frontend && npm ci
|
||||
|
||||
- name: Build application
|
||||
run: cd apps/frontend && npm run build
|
||||
|
||||
- name: Package macOS (Intel)
|
||||
run: cd apps/frontend && npm run package:mac -- --arch=x64
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
CSC_LINK: ${{ secrets.MAC_CERTIFICATE }}
|
||||
CSC_KEY_PASSWORD: ${{ secrets.MAC_CERTIFICATE_PASSWORD }}
|
||||
|
||||
- name: Notarize macOS Intel app
|
||||
env:
|
||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
|
||||
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
||||
run: |
|
||||
if [ -z "$APPLE_ID" ]; then
|
||||
echo "Skipping notarization: APPLE_ID not configured"
|
||||
exit 0
|
||||
fi
|
||||
cd apps/frontend
|
||||
for dmg in dist/*.dmg; do
|
||||
echo "Notarizing $dmg..."
|
||||
xcrun notarytool submit "$dmg" \
|
||||
--apple-id "$APPLE_ID" \
|
||||
--password "$APPLE_APP_SPECIFIC_PASSWORD" \
|
||||
--team-id "$APPLE_TEAM_ID" \
|
||||
--wait
|
||||
xcrun stapler staple "$dmg"
|
||||
echo "Successfully notarized and stapled $dmg"
|
||||
done
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: macos-intel-builds
|
||||
path: |
|
||||
apps/frontend/dist/*.dmg
|
||||
apps/frontend/dist/*.zip
|
||||
|
||||
# Apple Silicon build on ARM64 runner for native compilation
|
||||
build-macos-arm64:
|
||||
needs: update-version
|
||||
runs-on: macos-15
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: v${{ needs.update-version.outputs.version }}
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '24'
|
||||
|
||||
- name: Get npm cache directory
|
||||
id: npm-cache
|
||||
run: echo "dir=$(npm config get cache)" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ steps.npm-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
|
||||
restore-keys: ${{ runner.os }}-npm-
|
||||
|
||||
- name: Install dependencies
|
||||
run: cd apps/frontend && npm ci
|
||||
|
||||
- name: Build application
|
||||
run: cd apps/frontend && npm run build
|
||||
|
||||
- name: Package macOS (Apple Silicon)
|
||||
run: cd apps/frontend && npm run package:mac -- --arch=arm64
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
CSC_LINK: ${{ secrets.MAC_CERTIFICATE }}
|
||||
CSC_KEY_PASSWORD: ${{ secrets.MAC_CERTIFICATE_PASSWORD }}
|
||||
|
||||
- name: Notarize macOS ARM64 app
|
||||
env:
|
||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
|
||||
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
||||
run: |
|
||||
if [ -z "$APPLE_ID" ]; then
|
||||
echo "Skipping notarization: APPLE_ID not configured"
|
||||
exit 0
|
||||
fi
|
||||
cd apps/frontend
|
||||
for dmg in dist/*.dmg; do
|
||||
echo "Notarizing $dmg..."
|
||||
xcrun notarytool submit "$dmg" \
|
||||
--apple-id "$APPLE_ID" \
|
||||
--password "$APPLE_APP_SPECIFIC_PASSWORD" \
|
||||
--team-id "$APPLE_TEAM_ID" \
|
||||
--wait
|
||||
xcrun stapler staple "$dmg"
|
||||
echo "Successfully notarized and stapled $dmg"
|
||||
done
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: macos-arm64-builds
|
||||
path: |
|
||||
apps/frontend/dist/*.dmg
|
||||
apps/frontend/dist/*.zip
|
||||
|
||||
build-windows:
|
||||
needs: update-version
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: v${{ needs.update-version.outputs.version }}
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '24'
|
||||
|
||||
- name: Get npm cache directory
|
||||
id: npm-cache
|
||||
shell: bash
|
||||
run: echo "dir=$(npm config get cache)" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ steps.npm-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
|
||||
restore-keys: ${{ runner.os }}-npm-
|
||||
|
||||
- name: Install dependencies
|
||||
run: cd apps/frontend && npm ci
|
||||
|
||||
- name: Build application
|
||||
run: cd apps/frontend && npm run build
|
||||
|
||||
- name: Package Windows
|
||||
run: cd apps/frontend && npm run package:win
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
CSC_LINK: ${{ secrets.WIN_CERTIFICATE }}
|
||||
CSC_KEY_PASSWORD: ${{ secrets.WIN_CERTIFICATE_PASSWORD }}
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: windows-builds
|
||||
path: |
|
||||
apps/frontend/dist/*.exe
|
||||
|
||||
build-linux:
|
||||
needs: update-version
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: v${{ needs.update-version.outputs.version }}
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '24'
|
||||
|
||||
- name: Get npm cache directory
|
||||
id: npm-cache
|
||||
run: echo "dir=$(npm config get cache)" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ steps.npm-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
|
||||
restore-keys: ${{ runner.os }}-npm-
|
||||
|
||||
- name: Install dependencies
|
||||
run: cd apps/frontend && npm ci
|
||||
|
||||
- name: Build application
|
||||
run: cd apps/frontend && npm run build
|
||||
|
||||
- name: Package Linux
|
||||
run: cd apps/frontend && npm run package:linux
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: linux-builds
|
||||
path: |
|
||||
apps/frontend/dist/*.AppImage
|
||||
apps/frontend/dist/*.deb
|
||||
|
||||
create-release:
|
||||
needs: [update-version, build-macos-intel, build-macos-arm64, build-windows, build-linux]
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.inputs.dry_run != 'true' }}
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: v${{ needs.update-version.outputs.version }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Download all artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: dist
|
||||
|
||||
- name: Flatten and validate artifacts
|
||||
run: |
|
||||
mkdir -p release-assets
|
||||
find dist -type f \( -name "*.dmg" -o -name "*.zip" -o -name "*.exe" -o -name "*.AppImage" -o -name "*.deb" \) -exec cp {} release-assets/ \;
|
||||
|
||||
# Validate that at least one artifact was copied
|
||||
artifact_count=$(find release-assets -type f \( -name "*.dmg" -o -name "*.zip" -o -name "*.exe" -o -name "*.AppImage" -o -name "*.deb" \) | wc -l)
|
||||
if [ "$artifact_count" -eq 0 ]; then
|
||||
echo "::error::No build artifacts found! Expected .dmg, .zip, .exe, .AppImage, or .deb files."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Found $artifact_count artifact(s):"
|
||||
ls -la release-assets/
|
||||
|
||||
- name: Generate checksums
|
||||
run: |
|
||||
cd release-assets
|
||||
sha256sum ./* > checksums.sha256
|
||||
cat checksums.sha256
|
||||
|
||||
- name: Create Beta Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
tag_name: v${{ needs.update-version.outputs.version }}
|
||||
name: v${{ needs.update-version.outputs.version }} (Beta)
|
||||
body: |
|
||||
## Beta Release v${{ needs.update-version.outputs.version }}
|
||||
|
||||
This is a **beta release** for testing new features. It may contain bugs or incomplete functionality.
|
||||
|
||||
### How to opt-in to beta updates
|
||||
1. Open Auto Claude
|
||||
2. Go to Settings > Updates
|
||||
3. Enable "Beta Updates" toggle
|
||||
|
||||
### Reporting Issues
|
||||
Please report any issues at https://github.com/AndyMik90/Auto-Claude/issues
|
||||
|
||||
---
|
||||
|
||||
**Full Changelog**: https://github.com/${{ github.repository }}/compare/main...v${{ needs.update-version.outputs.version }}
|
||||
files: release-assets/*
|
||||
draft: false
|
||||
prerelease: true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
dry-run-summary:
|
||||
needs: [update-version, build-macos-intel, build-macos-arm64, build-windows, build-linux]
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.inputs.dry_run == 'true' }}
|
||||
steps:
|
||||
- name: Download all artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: dist
|
||||
|
||||
- name: Dry run summary
|
||||
run: |
|
||||
echo "## Beta Release Dry Run Complete" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "**Version:** ${{ needs.update-version.outputs.version }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "Build artifacts created successfully:" >> $GITHUB_STEP_SUMMARY
|
||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
||||
find dist -type f \( -name "*.dmg" -o -name "*.zip" -o -name "*.exe" -o -name "*.AppImage" -o -name "*.deb" \) >> $GITHUB_STEP_SUMMARY
|
||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "To create a real release, run this workflow again with dry_run unchecked." >> $GITHUB_STEP_SUMMARY
|
||||
@@ -0,0 +1,109 @@
|
||||
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
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- 'apps/frontend/package.json'
|
||||
- 'package.json'
|
||||
|
||||
jobs:
|
||||
check-and-tag:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
outputs:
|
||||
should_release: ${{ steps.check.outputs.should_release }}
|
||||
new_version: ${{ steps.check.outputs.new_version }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Get package version
|
||||
id: package
|
||||
run: |
|
||||
VERSION=$(node -p "require('./apps/frontend/package.json').version")
|
||||
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
||||
echo "Package version: $VERSION"
|
||||
|
||||
- name: Get latest tag version
|
||||
id: latest_tag
|
||||
run: |
|
||||
# Get the latest version tag (v*)
|
||||
LATEST_TAG=$(git tag -l 'v*' --sort=-version:refname | head -n1)
|
||||
if [ -z "$LATEST_TAG" ]; then
|
||||
echo "No existing tags found"
|
||||
echo "version=0.0.0" >> $GITHUB_OUTPUT
|
||||
else
|
||||
# Remove 'v' prefix
|
||||
LATEST_VERSION=${LATEST_TAG#v}
|
||||
echo "version=$LATEST_VERSION" >> $GITHUB_OUTPUT
|
||||
echo "Latest tag: $LATEST_TAG (version: $LATEST_VERSION)"
|
||||
fi
|
||||
|
||||
- name: Check if release needed
|
||||
id: check
|
||||
run: |
|
||||
PACKAGE_VERSION="${{ steps.package.outputs.version }}"
|
||||
LATEST_VERSION="${{ steps.latest_tag.outputs.version }}"
|
||||
|
||||
echo "Comparing: package=$PACKAGE_VERSION vs latest_tag=$LATEST_VERSION"
|
||||
|
||||
# Use sort -V for version comparison
|
||||
HIGHER=$(printf '%s\n%s' "$PACKAGE_VERSION" "$LATEST_VERSION" | sort -V | tail -n1)
|
||||
|
||||
if [ "$HIGHER" = "$PACKAGE_VERSION" ] && [ "$PACKAGE_VERSION" != "$LATEST_VERSION" ]; then
|
||||
echo "should_release=true" >> $GITHUB_OUTPUT
|
||||
echo "new_version=$PACKAGE_VERSION" >> $GITHUB_OUTPUT
|
||||
echo "✅ New release needed: v$PACKAGE_VERSION"
|
||||
else
|
||||
echo "should_release=false" >> $GITHUB_OUTPUT
|
||||
echo "⏭️ No release needed (package version not newer than latest tag)"
|
||||
fi
|
||||
|
||||
- name: Create and push tag
|
||||
if: steps.check.outputs.should_release == 'true'
|
||||
run: |
|
||||
VERSION="${{ steps.check.outputs.new_version }}"
|
||||
TAG="v$VERSION"
|
||||
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
|
||||
echo "Creating tag: $TAG"
|
||||
git tag -a "$TAG" -m "Release $TAG"
|
||||
git push origin "$TAG"
|
||||
|
||||
echo "✅ Tag $TAG created and pushed"
|
||||
echo "🚀 This will trigger the release workflow"
|
||||
|
||||
- name: Summary
|
||||
run: |
|
||||
if [ "${{ steps.check.outputs.should_release }}" = "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 "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 "3. Create GitHub release" >> $GITHUB_STEP_SUMMARY
|
||||
echo "4. Update README with new version" >> $GITHUB_STEP_SUMMARY
|
||||
else
|
||||
echo "## ⏭️ No Release Needed" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "**Package version:** ${{ steps.package.outputs.version }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "**Latest tag:** v${{ steps.latest_tag.outputs.version }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "The package version is not newer than the latest tag." >> $GITHUB_STEP_SUMMARY
|
||||
echo "To trigger a release, bump the version using:" >> $GITHUB_STEP_SUMMARY
|
||||
echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
|
||||
echo "node scripts/bump-version.js patch # or minor/major" >> $GITHUB_STEP_SUMMARY
|
||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
@@ -431,3 +431,52 @@ jobs:
|
||||
prerelease: ${{ contains(github.ref, 'beta') || contains(github.ref, 'alpha') }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# Update README with new version after successful release
|
||||
update-readme:
|
||||
needs: [create-release]
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.dry_run != true) }}
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: main
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Extract version from tag
|
||||
id: version
|
||||
run: |
|
||||
# Extract version from tag (v2.7.2 -> 2.7.2)
|
||||
VERSION=${GITHUB_REF_NAME#v}
|
||||
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
||||
echo "Updating README to version: $VERSION"
|
||||
|
||||
- name: Update README.md
|
||||
run: |
|
||||
VERSION="${{ steps.version.outputs.version }}"
|
||||
|
||||
# Update version badge: version-X.Y.Z-blue
|
||||
sed -i "s/version-[0-9]*\.[0-9]*\.[0-9]*-blue/version-${VERSION}-blue/g" README.md
|
||||
|
||||
# Update download links: Auto-Claude-X.Y.Z
|
||||
sed -i "s/Auto-Claude-[0-9]*\.[0-9]*\.[0-9]*/Auto-Claude-${VERSION}/g" README.md
|
||||
|
||||
echo "README.md updated to version $VERSION"
|
||||
grep -E "(version-|Auto-Claude-)" README.md | head -10
|
||||
|
||||
- name: Commit and push README update
|
||||
run: |
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
|
||||
# Check if there are changes to commit
|
||||
if git diff --quiet README.md; then
|
||||
echo "No changes to README.md, skipping commit"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
git add README.md
|
||||
git commit -m "docs: update README to v${{ steps.version.outputs.version }} [skip ci]"
|
||||
git push origin main
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
name: Stale Issues
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 * * 0' # Every Sunday
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
steps:
|
||||
- uses: actions/stale@v9
|
||||
with:
|
||||
stale-issue-message: |
|
||||
This issue has been inactive for 60 days. It will be closed in 14 days if there's no activity.
|
||||
|
||||
- If this is still relevant, please comment or update the issue
|
||||
- If you're working on this, add the `in-progress` label
|
||||
close-issue-message: 'Closed due to inactivity. Feel free to reopen if still relevant.'
|
||||
stale-issue-label: 'stale'
|
||||
days-before-stale: 60
|
||||
days-before-close: 14
|
||||
exempt-issue-labels: 'priority/critical,priority/high,in-progress,blocked'
|
||||
@@ -0,0 +1,33 @@
|
||||
name: Welcome
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened]
|
||||
issues:
|
||||
types: [opened]
|
||||
|
||||
jobs:
|
||||
welcome:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/first-interaction@v1
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-message: |
|
||||
👋 Thanks for opening your first issue!
|
||||
|
||||
A maintainer will triage this soon. In the meantime:
|
||||
- Make sure you've provided all the requested info
|
||||
- Join our [Discord](https://discord.gg/KCXaPBr4Dj) for faster help
|
||||
pr-message: |
|
||||
🎉 Thanks for your first PR!
|
||||
|
||||
A maintainer will review it soon. Please make sure:
|
||||
- Your branch is synced with `main`
|
||||
- CI checks pass
|
||||
- You've followed our [contribution guide](CONTRIBUTING.md)
|
||||
|
||||
Welcome to the Auto-Claude community!
|
||||
@@ -103,15 +103,20 @@ python apps/backend/validate_spec.py --spec-dir apps/backend/specs/001-feature -
|
||||
|
||||
### Releases
|
||||
```bash
|
||||
# Automated version bump and release (recommended)
|
||||
# 1. Bump version on your branch (creates commit, no tag)
|
||||
node scripts/bump-version.js patch # 2.8.0 -> 2.8.1
|
||||
node scripts/bump-version.js minor # 2.8.0 -> 2.9.0
|
||||
node scripts/bump-version.js major # 2.8.0 -> 3.0.0
|
||||
node scripts/bump-version.js 2.9.0 # Set specific version
|
||||
|
||||
# Then push to trigger GitHub release workflows
|
||||
git push origin main
|
||||
git push origin v2.9.0
|
||||
# 2. Push and create PR to main
|
||||
git push origin your-branch
|
||||
gh pr create --base main
|
||||
|
||||
# 3. Merge PR → GitHub Actions automatically:
|
||||
# - Creates tag
|
||||
# - Builds all platforms
|
||||
# - Creates release with changelog
|
||||
# - Updates README
|
||||
```
|
||||
|
||||
See [RELEASE.md](RELEASE.md) for detailed release process documentation.
|
||||
|
||||
@@ -491,6 +491,35 @@ git branch -d release/v2.8.0
|
||||
git push origin --delete release/v2.8.0
|
||||
```
|
||||
|
||||
### Beta Release Process (Maintainers)
|
||||
|
||||
Beta releases allow users to test new features before they're included in a stable release. Beta releases are published from the `develop` branch.
|
||||
|
||||
**Creating a Beta Release:**
|
||||
|
||||
1. Go to **Actions** → **Beta Release** workflow in GitHub
|
||||
2. Click **Run workflow**
|
||||
3. Enter the beta version (e.g., `2.8.0-beta.1`)
|
||||
4. Optionally enable dry run to test without publishing
|
||||
5. Click **Run workflow**
|
||||
|
||||
The workflow will:
|
||||
- Validate the version format
|
||||
- Update `package.json` on develop
|
||||
- Create and push a tag (e.g., `v2.8.0-beta.1`)
|
||||
- Build installers for all platforms
|
||||
- Create a GitHub pre-release
|
||||
|
||||
**Version Format:**
|
||||
```
|
||||
X.Y.Z-beta.N (e.g., 2.8.0-beta.1, 2.8.0-beta.2)
|
||||
X.Y.Z-alpha.N (e.g., 2.8.0-alpha.1)
|
||||
X.Y.Z-rc.N (e.g., 2.8.0-rc.1)
|
||||
```
|
||||
|
||||
**For Users:**
|
||||
Users can opt into beta updates in Settings → Updates → "Beta Updates" toggle. When enabled, the app will check for and install beta versions. Users can switch back to stable at any time.
|
||||
|
||||
### Hotfix Workflow
|
||||
|
||||
For urgent production fixes that can't wait for the normal release cycle:
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||

|
||||
|
||||
[](https://github.com/AndyMik90/Auto-Claude/releases/latest)
|
||||
[](https://github.com/AndyMik90/Auto-Claude/releases/latest)
|
||||
[](./agpl-3.0.txt)
|
||||
[](https://discord.gg/KCXaPBr4Dj)
|
||||
[](https://github.com/AndyMik90/Auto-Claude/actions)
|
||||
@@ -17,11 +17,11 @@ Get the latest pre-built release for your platform:
|
||||
|
||||
| Platform | Download | Notes |
|
||||
|----------|----------|-------|
|
||||
| **Windows** | [Auto-Claude-2.7.2.exe](https://github.com/AndyMik90/Auto-Claude/releases/latest) | Installer (NSIS) |
|
||||
| **macOS (Apple Silicon)** | [Auto-Claude-2.7.2-arm64.dmg](https://github.com/AndyMik90/Auto-Claude/releases/latest) | M1/M2/M3 Macs |
|
||||
| **macOS (Intel)** | [Auto-Claude-2.7.2-x64.dmg](https://github.com/AndyMik90/Auto-Claude/releases/latest) | Intel Macs |
|
||||
| **Linux** | [Auto-Claude-2.7.2.AppImage](https://github.com/AndyMik90/Auto-Claude/releases/latest) | Universal |
|
||||
| **Linux (Debian)** | [Auto-Claude-2.7.2.deb](https://github.com/AndyMik90/Auto-Claude/releases/latest) | Ubuntu/Debian |
|
||||
| **Windows** | [Auto-Claude-2.7.1.exe](https://github.com/AndyMik90/Auto-Claude/releases/latest) | Installer (NSIS) |
|
||||
| **macOS (Apple Silicon)** | [Auto-Claude-2.7.1-arm64.dmg](https://github.com/AndyMik90/Auto-Claude/releases/latest) | M1/M2/M3 Macs |
|
||||
| **macOS (Intel)** | [Auto-Claude-2.7.1-x64.dmg](https://github.com/AndyMik90/Auto-Claude/releases/latest) | Intel Macs |
|
||||
| **Linux** | [Auto-Claude-2.7.1.AppImage](https://github.com/AndyMik90/Auto-Claude/releases/latest) | Universal |
|
||||
| **Linux (Debian)** | [Auto-Claude-2.7.1.deb](https://github.com/AndyMik90/Auto-Claude/releases/latest) | Ubuntu/Debian |
|
||||
|
||||
> All releases include SHA256 checksums and VirusTotal scan results for security verification.
|
||||
|
||||
|
||||
+188
@@ -0,0 +1,188 @@
|
||||
# Release Process
|
||||
|
||||
This document describes how releases are created for Auto Claude.
|
||||
|
||||
## Overview
|
||||
|
||||
Auto Claude uses an automated release pipeline that ensures releases are only published after all builds succeed. This prevents version mismatches between documentation and actual releases.
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ RELEASE FLOW │
|
||||
├─────────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ develop branch main branch │
|
||||
│ ────────────── ─────────── │
|
||||
│ │ │ │
|
||||
│ │ 1. bump-version.js │ │
|
||||
│ │ (creates commit) │ │
|
||||
│ │ │ │
|
||||
│ ▼ │ │
|
||||
│ ┌─────────┐ │ │
|
||||
│ │ v2.8.0 │ 2. Create PR │ │
|
||||
│ │ commit │ ────────────────────► │ │
|
||||
│ └─────────┘ │ │
|
||||
│ │ │
|
||||
│ 3. Merge PR ▼ │
|
||||
│ ┌──────────┐ │
|
||||
│ │ v2.8.0 │ │
|
||||
│ │ on main │ │
|
||||
│ └────┬─────┘ │
|
||||
│ │ │
|
||||
│ ┌───────────────────┴───────────────────┐ │
|
||||
│ │ GitHub Actions (automatic) │ │
|
||||
│ ├───────────────────────────────────────┤ │
|
||||
│ │ 4. prepare-release.yml │ │
|
||||
│ │ - Detects version > latest tag │ │
|
||||
│ │ - Creates tag v2.8.0 │ │
|
||||
│ │ │ │
|
||||
│ │ 5. release.yml (triggered by tag) │ │
|
||||
│ │ - Builds macOS (Intel + ARM) │ │
|
||||
│ │ - Builds Windows │ │
|
||||
│ │ - Builds Linux │ │
|
||||
│ │ - Generates changelog │ │
|
||||
│ │ - Creates GitHub release │ │
|
||||
│ │ - Updates README │ │
|
||||
│ └───────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## For Maintainers: Creating a Release
|
||||
|
||||
### Step 1: Bump the Version
|
||||
|
||||
On your development branch (typically `develop` or a feature branch):
|
||||
|
||||
```bash
|
||||
# Navigate to project root
|
||||
cd /path/to/auto-claude
|
||||
|
||||
# Bump version (choose one)
|
||||
node scripts/bump-version.js patch # 2.7.1 -> 2.7.2 (bug fixes)
|
||||
node scripts/bump-version.js minor # 2.7.1 -> 2.8.0 (new features)
|
||||
node scripts/bump-version.js major # 2.7.1 -> 3.0.0 (breaking changes)
|
||||
node scripts/bump-version.js 2.8.0 # Set specific version
|
||||
```
|
||||
|
||||
This will:
|
||||
- Update `apps/frontend/package.json`
|
||||
- Update `package.json` (root)
|
||||
- Update `apps/backend/__init__.py`
|
||||
- Create a commit with message `chore: bump version to X.Y.Z`
|
||||
|
||||
### Step 2: Push and Create PR
|
||||
|
||||
```bash
|
||||
# Push your branch
|
||||
git push origin your-branch
|
||||
|
||||
# Create PR to main (via GitHub UI or gh CLI)
|
||||
gh pr create --base main --title "Release v2.8.0"
|
||||
```
|
||||
|
||||
### Step 3: 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:
|
||||
- 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
|
||||
|
||||
### Step 4: Verify
|
||||
|
||||
After merging, check:
|
||||
- [GitHub Actions](https://github.com/AndyMik90/Auto-Claude/actions) - ensure all workflows pass
|
||||
- [Releases](https://github.com/AndyMik90/Auto-Claude/releases) - verify release was created
|
||||
- [README](https://github.com/AndyMik90/Auto-Claude#download) - confirm version updated
|
||||
|
||||
## Version Numbering
|
||||
|
||||
We follow [Semantic Versioning](https://semver.org/):
|
||||
|
||||
- **MAJOR** (X.0.0): Breaking changes, incompatible API changes
|
||||
- **MINOR** (0.X.0): New features, backwards compatible
|
||||
- **PATCH** (0.0.X): Bug fixes, backwards compatible
|
||||
|
||||
## Changelog Generation
|
||||
|
||||
Changelogs are automatically generated from merged PRs using [Release Drafter](https://github.com/release-drafter/release-drafter).
|
||||
|
||||
### PR Labels for Changelog Categories
|
||||
|
||||
| Label | Category |
|
||||
|-------|----------|
|
||||
| `feature`, `enhancement` | New Features |
|
||||
| `bug`, `fix` | Bug Fixes |
|
||||
| `improvement`, `refactor` | Improvements |
|
||||
| `documentation` | Documentation |
|
||||
| (any other) | Other Changes |
|
||||
|
||||
**Tip:** Add appropriate labels to your PRs for better changelog organization.
|
||||
|
||||
## Workflows
|
||||
|
||||
| Workflow | Trigger | Purpose |
|
||||
|----------|---------|---------|
|
||||
| `prepare-release.yml` | Push to `main` | Detects version bump, creates tag |
|
||||
| `release.yml` | Tag `v*` pushed | Builds binaries, 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 |
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Release didn't trigger after merge
|
||||
|
||||
1. Check if version in `package.json` is greater than latest tag:
|
||||
```bash
|
||||
git tag -l 'v*' --sort=-version:refname | head -1
|
||||
cat apps/frontend/package.json | grep version
|
||||
```
|
||||
|
||||
2. Ensure the merge commit touched `package.json`:
|
||||
```bash
|
||||
git diff HEAD~1 --name-only | grep package.json
|
||||
```
|
||||
|
||||
### Build failed after tag was created
|
||||
|
||||
- The release won't be published if builds fail
|
||||
- Fix the issue and create a new patch version
|
||||
- Don't reuse failed version numbers
|
||||
|
||||
### README shows wrong version
|
||||
|
||||
- README is only updated after successful release
|
||||
- If release failed, README keeps the previous version (this is intentional)
|
||||
- Once you successfully release, README will update automatically
|
||||
|
||||
## Manual Release (Emergency Only)
|
||||
|
||||
In rare cases where you need to bypass the automated flow:
|
||||
|
||||
```bash
|
||||
# Create tag manually (NOT RECOMMENDED)
|
||||
git tag -a v2.8.0 -m "Release v2.8.0"
|
||||
git push origin v2.8.0
|
||||
|
||||
# This will trigger release.yml directly
|
||||
```
|
||||
|
||||
**Warning:** Only do this if you're certain the version in package.json matches the tag.
|
||||
|
||||
## Security
|
||||
|
||||
- All macOS binaries are code signed with Apple Developer certificate
|
||||
- All macOS binaries are notarized by Apple
|
||||
- Windows binaries are code signed
|
||||
- All binaries are scanned with VirusTotal
|
||||
- SHA256 checksums are generated for all artifacts
|
||||
@@ -30,6 +30,21 @@ const DEBUG_UPDATER = process.env.DEBUG_UPDATER === 'true' || process.env.NODE_E
|
||||
autoUpdater.autoDownload = true; // Automatically download updates when available
|
||||
autoUpdater.autoInstallOnAppQuit = true; // Automatically install on app quit
|
||||
|
||||
// Update channels: 'latest' for stable, 'beta' for pre-release
|
||||
type UpdateChannel = 'latest' | 'beta';
|
||||
|
||||
/**
|
||||
* Set the update channel for electron-updater.
|
||||
* - 'latest': Only receive stable releases (default)
|
||||
* - 'beta': Receive pre-release/beta versions
|
||||
*
|
||||
* @param channel - The update channel to use
|
||||
*/
|
||||
export function setUpdateChannel(channel: UpdateChannel): void {
|
||||
autoUpdater.channel = channel;
|
||||
console.warn(`[app-updater] Update channel set to: ${channel}`);
|
||||
}
|
||||
|
||||
// Enable more verbose logging in debug mode
|
||||
if (DEBUG_UPDATER) {
|
||||
autoUpdater.logger = {
|
||||
@@ -49,15 +64,21 @@ let mainWindow: BrowserWindow | null = null;
|
||||
* Should only be called in production (app.isPackaged).
|
||||
*
|
||||
* @param window - The main BrowserWindow for sending update events
|
||||
* @param betaUpdates - Whether to receive beta/pre-release updates
|
||||
*/
|
||||
export function initializeAppUpdater(window: BrowserWindow): void {
|
||||
export function initializeAppUpdater(window: BrowserWindow, betaUpdates = false): void {
|
||||
mainWindow = window;
|
||||
|
||||
// Set update channel based on user preference
|
||||
const channel = betaUpdates ? 'beta' : 'latest';
|
||||
setUpdateChannel(channel);
|
||||
|
||||
// Log updater configuration
|
||||
console.warn('[app-updater] ========================================');
|
||||
console.warn('[app-updater] Initializing app auto-updater');
|
||||
console.warn('[app-updater] App packaged:', app.isPackaged);
|
||||
console.warn('[app-updater] Current version:', autoUpdater.currentVersion.version);
|
||||
console.warn('[app-updater] Update channel:', channel);
|
||||
console.warn('[app-updater] Auto-download enabled:', autoUpdater.autoDownload);
|
||||
console.warn('[app-updater] Debug mode:', DEBUG_UPDATER);
|
||||
console.warn('[app-updater] ========================================');
|
||||
|
||||
@@ -9,6 +9,18 @@ import { pythonEnvManager } from './python-env-manager';
|
||||
import { getUsageMonitor } from './claude-profile/usage-monitor';
|
||||
import { initializeUsageMonitorForwarding } from './ipc-handlers/terminal-handlers';
|
||||
import { initializeAppUpdater } from './app-updater';
|
||||
import { DEFAULT_APP_SETTINGS } from '../shared/constants';
|
||||
import { readSettingsFile } from './settings-utils';
|
||||
import type { AppSettings } from '../shared/types';
|
||||
|
||||
/**
|
||||
* Load app settings synchronously (for use during startup).
|
||||
* This is a simple merge with defaults - no migrations or auto-detection.
|
||||
*/
|
||||
function loadSettingsSync(): AppSettings {
|
||||
const savedSettings = readSettingsFile();
|
||||
return { ...DEFAULT_APP_SETTINGS, ...savedSettings } as AppSettings;
|
||||
}
|
||||
|
||||
// Get icon path based on platform
|
||||
function getIconPath(): string {
|
||||
@@ -168,8 +180,13 @@ app.whenReady().then(() => {
|
||||
// Initialize app auto-updater (only in production, or when DEBUG_UPDATER is set)
|
||||
const forceUpdater = process.env.DEBUG_UPDATER === 'true';
|
||||
if (app.isPackaged || forceUpdater) {
|
||||
initializeAppUpdater(mainWindow);
|
||||
// Load settings to get beta updates preference
|
||||
const settings = loadSettingsSync();
|
||||
const betaUpdates = settings.betaUpdates ?? false;
|
||||
|
||||
initializeAppUpdater(mainWindow, betaUpdates);
|
||||
console.warn('[main] App auto-updater initialized');
|
||||
console.warn(`[main] Beta updates: ${betaUpdates ? 'enabled' : 'disabled'}`);
|
||||
if (forceUpdater && !app.isPackaged) {
|
||||
console.warn('[main] Updater forced in dev mode via DEBUG_UPDATER=true');
|
||||
console.warn('[main] Note: Updates won\'t actually work in dev mode');
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ipcMain, dialog, app, shell } from 'electron';
|
||||
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
|
||||
import { existsSync, writeFileSync, mkdirSync } from 'fs';
|
||||
import { execSync } from 'child_process';
|
||||
import path from 'path';
|
||||
import { is } from '@electron-toolkit/utils';
|
||||
@@ -11,8 +11,10 @@ import type {
|
||||
import { AgentManager } from '../agent';
|
||||
import type { BrowserWindow } from 'electron';
|
||||
import { getEffectiveVersion } from '../auto-claude-updater';
|
||||
import { setUpdateChannel } from '../app-updater';
|
||||
import { getSettingsPath, readSettingsFile } from '../settings-utils';
|
||||
|
||||
const settingsPath = path.join(app.getPath('userData'), 'settings.json');
|
||||
const settingsPath = getSettingsPath();
|
||||
|
||||
/**
|
||||
* Auto-detect the auto-claude source path relative to the app location.
|
||||
@@ -101,18 +103,11 @@ export function registerSettingsHandlers(
|
||||
ipcMain.handle(
|
||||
IPC_CHANNELS.SETTINGS_GET,
|
||||
async (): Promise<IPCResult<AppSettings>> => {
|
||||
let settings: AppSettings = { ...DEFAULT_APP_SETTINGS };
|
||||
// Load settings using shared helper and merge with defaults
|
||||
const savedSettings = readSettingsFile();
|
||||
const settings: AppSettings = { ...DEFAULT_APP_SETTINGS, ...savedSettings };
|
||||
let needsSave = false;
|
||||
|
||||
if (existsSync(settingsPath)) {
|
||||
try {
|
||||
const content = readFileSync(settingsPath, 'utf-8');
|
||||
settings = { ...settings, ...JSON.parse(content) };
|
||||
} catch {
|
||||
// Use defaults
|
||||
}
|
||||
}
|
||||
|
||||
// Migration: Set agent profile to 'auto' for users who haven't made a selection (one-time)
|
||||
// This ensures new users get the optimized 'auto' profile as the default
|
||||
// while preserving existing user preferences
|
||||
@@ -151,12 +146,9 @@ export function registerSettingsHandlers(
|
||||
IPC_CHANNELS.SETTINGS_SAVE,
|
||||
async (_, settings: Partial<AppSettings>): Promise<IPCResult> => {
|
||||
try {
|
||||
let currentSettings = DEFAULT_APP_SETTINGS;
|
||||
if (existsSync(settingsPath)) {
|
||||
const content = readFileSync(settingsPath, 'utf-8');
|
||||
currentSettings = { ...currentSettings, ...JSON.parse(content) };
|
||||
}
|
||||
|
||||
// Load current settings using shared helper
|
||||
const savedSettings = readSettingsFile();
|
||||
const currentSettings = { ...DEFAULT_APP_SETTINGS, ...savedSettings };
|
||||
const newSettings = { ...currentSettings, ...settings };
|
||||
writeFileSync(settingsPath, JSON.stringify(newSettings, null, 2));
|
||||
|
||||
@@ -165,6 +157,12 @@ export function registerSettingsHandlers(
|
||||
agentManager.configure(settings.pythonPath, settings.autoBuildPath);
|
||||
}
|
||||
|
||||
// Update auto-updater channel if betaUpdates setting changed
|
||||
if (settings.betaUpdates !== undefined) {
|
||||
const channel = settings.betaUpdates ? 'beta' : 'latest';
|
||||
setUpdateChannel(channel);
|
||||
}
|
||||
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
return {
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Shared settings utilities for main process
|
||||
*
|
||||
* This module provides low-level settings file operations used by both
|
||||
* the main process startup (index.ts) and the IPC handlers (settings-handlers.ts).
|
||||
*
|
||||
* NOTE: This module intentionally does NOT perform migrations or auto-detection.
|
||||
* Those are handled by the IPC handlers where they have full context.
|
||||
*/
|
||||
|
||||
import { app } from 'electron';
|
||||
import { existsSync, readFileSync } from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
/**
|
||||
* Get the path to the settings file
|
||||
*/
|
||||
export function getSettingsPath(): string {
|
||||
return path.join(app.getPath('userData'), 'settings.json');
|
||||
}
|
||||
|
||||
/**
|
||||
* Read and parse settings from disk.
|
||||
* Returns the raw parsed settings object, or undefined if the file doesn't exist or fails to parse.
|
||||
*
|
||||
* This function does NOT merge with defaults or perform any migrations.
|
||||
* Callers are responsible for merging with DEFAULT_APP_SETTINGS.
|
||||
*/
|
||||
export function readSettingsFile(): Record<string, unknown> | undefined {
|
||||
const settingsPath = getSettingsPath();
|
||||
|
||||
if (!existsSync(settingsPath)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
try {
|
||||
const content = readFileSync(settingsPath, 'utf-8');
|
||||
return JSON.parse(content);
|
||||
} catch {
|
||||
// Return undefined on parse error - caller will use defaults
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
@@ -419,6 +419,21 @@ export function AdvancedSettings({ settings, onSettingsChange, section, version
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between p-4 rounded-lg border border-border">
|
||||
<div className="space-y-1">
|
||||
<Label className="font-medium text-foreground">Beta Updates</Label>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Receive pre-release beta versions with new features (may be less stable)
|
||||
</p>
|
||||
</div>
|
||||
<Switch
|
||||
checked={settings.betaUpdates ?? false}
|
||||
onCheckedChange={(checked) =>
|
||||
onSettingsChange({ ...settings, betaUpdates: checked })
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</SettingsSection>
|
||||
);
|
||||
|
||||
@@ -42,7 +42,9 @@ export const DEFAULT_APP_SETTINGS = {
|
||||
changelogAudience: 'user-facing' as const,
|
||||
changelogEmojiLevel: 'none' as const,
|
||||
// UI Scale (default 100% - standard size)
|
||||
uiScale: UI_SCALE_DEFAULT
|
||||
uiScale: UI_SCALE_DEFAULT,
|
||||
// Beta updates opt-in (receive pre-release versions)
|
||||
betaUpdates: false
|
||||
};
|
||||
|
||||
// ============================================
|
||||
|
||||
@@ -108,6 +108,8 @@ export interface AppSettings {
|
||||
changelogEmojiLevel?: ChangelogEmojiLevel;
|
||||
// UI Scale setting (75-200%, default 100)
|
||||
uiScale?: number;
|
||||
// Beta updates opt-in (receive pre-release updates)
|
||||
betaUpdates?: boolean;
|
||||
// Migration flags (internal use)
|
||||
_migratedAgentProfileToAuto?: boolean;
|
||||
}
|
||||
|
||||
+30
-38
@@ -3,8 +3,8 @@
|
||||
/**
|
||||
* Version Bump Script
|
||||
*
|
||||
* Automatically bumps the version in package.json and creates a git tag.
|
||||
* This ensures version consistency between package.json and git tags.
|
||||
* Bumps the version in package.json files. When this commit is merged to main,
|
||||
* GitHub Actions will automatically create the tag and trigger the release.
|
||||
*
|
||||
* Usage:
|
||||
* node scripts/bump-version.js <major|minor|patch|x.y.z>
|
||||
@@ -14,6 +14,17 @@
|
||||
* node scripts/bump-version.js minor # 2.5.5 -> 2.6.0
|
||||
* node scripts/bump-version.js major # 2.5.5 -> 3.0.0
|
||||
* node scripts/bump-version.js 2.6.0 # Set to specific version
|
||||
*
|
||||
* Release Flow:
|
||||
* 1. Run this script on develop branch
|
||||
* 2. Push to develop
|
||||
* 3. Create PR: develop → main
|
||||
* 4. Merge PR
|
||||
* 5. GitHub Actions automatically:
|
||||
* - Creates git tag
|
||||
* - Builds binaries
|
||||
* - Creates GitHub release
|
||||
* - Updates README
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
@@ -138,27 +149,6 @@ function updateBackendInit(newVersion) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Update README.md version references
|
||||
function updateReadme(newVersion, oldVersion) {
|
||||
const readmePath = path.join(__dirname, '..', 'README.md');
|
||||
|
||||
if (!fs.existsSync(readmePath)) {
|
||||
warning(`README.md not found at ${readmePath}, skipping`);
|
||||
return false;
|
||||
}
|
||||
|
||||
let content = fs.readFileSync(readmePath, 'utf8');
|
||||
|
||||
// Update version badge: version-X.Y.Z-blue
|
||||
content = content.replace(/version-[\d.]+(-\w+)?-blue/g, `version-${newVersion}-blue`);
|
||||
|
||||
// Update download links: Auto-Claude-X.Y.Z
|
||||
content = content.replace(/Auto-Claude-[\d.]+/g, `Auto-Claude-${newVersion}`);
|
||||
|
||||
fs.writeFileSync(readmePath, content);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Main function
|
||||
function main() {
|
||||
const bumpType = process.argv[2];
|
||||
@@ -204,31 +194,33 @@ function main() {
|
||||
success('Updated apps/backend/__init__.py');
|
||||
}
|
||||
|
||||
info('Updating README.md...');
|
||||
if (updateReadme(newVersion, currentVersion)) {
|
||||
success('Updated README.md');
|
||||
}
|
||||
// Note: README.md is NOT updated here - it gets updated by the release workflow
|
||||
// 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
|
||||
info('Creating git commit...');
|
||||
exec('git add apps/frontend/package.json package.json apps/backend/__init__.py README.md');
|
||||
exec('git add apps/frontend/package.json package.json apps/backend/__init__.py');
|
||||
exec(`git commit -m "chore: bump version to ${newVersion}"`);
|
||||
success(`Created commit: "chore: bump version to ${newVersion}"`);
|
||||
|
||||
// 7. Create git tag
|
||||
info('Creating git tag...');
|
||||
exec(`git tag -a v${newVersion} -m "Release v${newVersion}"`);
|
||||
success(`Created tag: v${newVersion}`);
|
||||
// Note: Tags are NOT created here anymore. GitHub Actions will create the tag
|
||||
// when this commit is merged to main, ensuring releases only happen after
|
||||
// successful builds.
|
||||
|
||||
// 8. Instructions
|
||||
// 7. Instructions
|
||||
log('\n📋 Next steps:', colors.yellow);
|
||||
log(` 1. Review the changes: git log -1`, colors.yellow);
|
||||
log(` 2. Push the commit: git push origin <branch-name>`, colors.yellow);
|
||||
log(` 3. Push the tag: git push origin v${newVersion}`, colors.yellow);
|
||||
log(` 4. Create a GitHub release from the tag\n`, 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);
|
||||
log(` - Create tag v${newVersion}`, colors.yellow);
|
||||
log(` - Build binaries for all platforms`, colors.yellow);
|
||||
log(` - Create GitHub release with changelog`, colors.yellow);
|
||||
log(` - Update README with new version\n`, colors.yellow);
|
||||
|
||||
warning('Note: The commit and tag have been created locally but NOT pushed.');
|
||||
warning('Please review and push manually when ready.');
|
||||
warning('Note: The commit has been created locally but NOT pushed.');
|
||||
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