mirror of
https://github.com/Novattz/creamlinux-installer.git
synced 2026-01-24 20:32:51 -05:00
patch
This commit is contained in:
305
.github/workflows/release.yml
vendored
305
.github/workflows/release.yml
vendored
@@ -1,305 +0,0 @@
|
|||||||
name: 'Release CreamLinux'
|
|
||||||
|
|
||||||
# Run on manual dispatch with version info and release notes
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
version_type:
|
|
||||||
description: 'Version increment type (patch, minor, major)'
|
|
||||||
required: true
|
|
||||||
default: 'patch'
|
|
||||||
type: choice
|
|
||||||
options:
|
|
||||||
- patch
|
|
||||||
- minor
|
|
||||||
- major
|
|
||||||
custom_release_notes:
|
|
||||||
description: 'Custom release notes (leave empty for auto-generated)'
|
|
||||||
required: false
|
|
||||||
type: string
|
|
||||||
dry_run:
|
|
||||||
description: 'Perform a dry run (no actual release)'
|
|
||||||
required: false
|
|
||||||
default: false
|
|
||||||
type: boolean
|
|
||||||
|
|
||||||
env:
|
|
||||||
CARGO_TERM_COLOR: always
|
|
||||||
CARGO_INCREMENTAL: 0
|
|
||||||
RUST_BACKTRACE: short
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
version-bump:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
outputs:
|
|
||||||
new_version: ${{ steps.version.outputs.new_version }}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0 # Get all history for changelog
|
|
||||||
|
|
||||||
- name: Setup Node.js
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 20
|
|
||||||
cache: 'npm'
|
|
||||||
|
|
||||||
- name: Calculate New Version
|
|
||||||
id: version
|
|
||||||
run: |
|
|
||||||
# Read current version from package.json
|
|
||||||
CURRENT_VERSION=$(node -p "require('./package.json').version")
|
|
||||||
echo "Current version: $CURRENT_VERSION"
|
|
||||||
|
|
||||||
# Split version into major.minor.patch
|
|
||||||
IFS='.' read -r major minor patch <<< "$CURRENT_VERSION"
|
|
||||||
|
|
||||||
# Increment based on input
|
|
||||||
if [[ "${{ github.event.inputs.version_type }}" == "major" ]]; then
|
|
||||||
major=$((major + 1))
|
|
||||||
minor=0
|
|
||||||
patch=0
|
|
||||||
elif [[ "${{ github.event.inputs.version_type }}" == "minor" ]]; then
|
|
||||||
minor=$((minor + 1))
|
|
||||||
patch=0
|
|
||||||
else # patch
|
|
||||||
patch=$((patch + 1))
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create new version
|
|
||||||
NEW_VERSION="${major}.${minor}.${patch}"
|
|
||||||
echo "New version: $NEW_VERSION"
|
|
||||||
|
|
||||||
# Set output for later steps
|
|
||||||
echo "new_version=${NEW_VERSION}" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
- name: Update Version in Files
|
|
||||||
env:
|
|
||||||
NEW_VERSION: ${{ steps.version.outputs.new_version }}
|
|
||||||
run: |
|
|
||||||
# Update package.json
|
|
||||||
npm version $NEW_VERSION --no-git-tag-version
|
|
||||||
|
|
||||||
# Update Cargo.toml
|
|
||||||
sed -i "s/^version = \".*\"/version = \"$NEW_VERSION\"/" src-tauri/Cargo.toml
|
|
||||||
|
|
||||||
# Update tauri.conf.json
|
|
||||||
sed -i "s/\"version\": \".*\"/\"version\": \"$NEW_VERSION\"/" src-tauri/tauri.conf.json
|
|
||||||
|
|
||||||
- name: Generate Changelog
|
|
||||||
id: changelog
|
|
||||||
if: github.event.inputs.custom_release_notes == ''
|
|
||||||
run: |
|
|
||||||
# Get all commit messages since the last tag
|
|
||||||
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
|
|
||||||
|
|
||||||
if [ -z "$LATEST_TAG" ]; then
|
|
||||||
COMMITS=$(git log --pretty=format:"- %s" --no-merges)
|
|
||||||
else
|
|
||||||
COMMITS=$(git log $LATEST_TAG..HEAD --pretty=format:"- %s" --no-merges)
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Generate changelog from commits
|
|
||||||
CHANGELOG="## Changes\n\n$COMMITS"
|
|
||||||
|
|
||||||
# Save changelog to a file (multiline to output)
|
|
||||||
echo -e "$CHANGELOG" > changelog.md
|
|
||||||
echo "Generated changelog from commit messages"
|
|
||||||
|
|
||||||
- name: Commit Version Changes
|
|
||||||
if: ${{ !github.event.inputs.dry_run }}
|
|
||||||
env:
|
|
||||||
NEW_VERSION: ${{ steps.version.outputs.new_version }}
|
|
||||||
run: |
|
|
||||||
git config --local user.email "action@github.com"
|
|
||||||
git config --local user.name "GitHub Action"
|
|
||||||
git add package.json src-tauri/Cargo.toml src-tauri/tauri.conf.json
|
|
||||||
git commit -m "chore: bump version to $NEW_VERSION [skip ci]"
|
|
||||||
git tag -a "v$NEW_VERSION" -m "Version $NEW_VERSION"
|
|
||||||
git push origin HEAD:${GITHUB_REF#refs/heads/}
|
|
||||||
git push origin "v$NEW_VERSION"
|
|
||||||
|
|
||||||
# Upload changelog as an artifact for the publish-release job
|
|
||||||
- name: Upload Changelog
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: changelog
|
|
||||||
path: changelog.md
|
|
||||||
retention-days: 1
|
|
||||||
|
|
||||||
build-linux:
|
|
||||||
needs: version-bump
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
outputs:
|
|
||||||
appimage_path: ${{ steps.find-assets.outputs.appimage_path }}
|
|
||||||
deb_path: ${{ steps.find-assets.outputs.deb_path }}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
ref: v${{ needs.version-bump.outputs.new_version }}
|
|
||||||
|
|
||||||
- name: Setup Node.js
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 20
|
|
||||||
cache: 'npm'
|
|
||||||
|
|
||||||
- name: Install Rust toolchain
|
|
||||||
uses: dtolnay/rust-toolchain@stable
|
|
||||||
|
|
||||||
- name: Cache Rust dependencies
|
|
||||||
uses: Swatinem/rust-cache@v2
|
|
||||||
with:
|
|
||||||
workspaces: 'src-tauri -> target'
|
|
||||||
cache-on-failure: true
|
|
||||||
|
|
||||||
- name: Install system dependencies
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf
|
|
||||||
|
|
||||||
- name: Install frontend dependencies
|
|
||||||
run: npm install
|
|
||||||
|
|
||||||
- name: Quick lint and type-check
|
|
||||||
run: |
|
|
||||||
npm run lint
|
|
||||||
npx tsc --noEmit
|
|
||||||
|
|
||||||
- name: Build the app (optimized)
|
|
||||||
run: npm run tauri build
|
|
||||||
|
|
||||||
- name: Find build assets
|
|
||||||
id: find-assets
|
|
||||||
run: |
|
|
||||||
echo "appimage_path=$(find src-tauri/target/release/bundle/appimage -name "*.AppImage" | head -n 1)" >> $GITHUB_OUTPUT
|
|
||||||
echo "deb_path=$(find src-tauri/target/release/bundle/deb -name "*.deb" | head -n 1)" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
- name: Upload Linux builds as artifacts
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: linux-builds
|
|
||||||
path: |
|
|
||||||
${{ steps.find-assets.outputs.appimage_path }}
|
|
||||||
${{ steps.find-assets.outputs.deb_path }}
|
|
||||||
retention-days: 1
|
|
||||||
|
|
||||||
# Build for other platforms in parallel if needed - examples:
|
|
||||||
build-windows:
|
|
||||||
needs: version-bump
|
|
||||||
runs-on: windows-latest
|
|
||||||
if: false # Disabled until we add Windows build support
|
|
||||||
outputs:
|
|
||||||
msi_path: ${{ steps.find-assets.outputs.msi_path }}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
ref: v${{ needs.version-bump.outputs.new_version }}
|
|
||||||
|
|
||||||
- name: Setup Node.js
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 20
|
|
||||||
cache: 'npm'
|
|
||||||
|
|
||||||
- name: Install Rust toolchain
|
|
||||||
uses: dtolnay/rust-toolchain@stable
|
|
||||||
|
|
||||||
- name: Cache Rust dependencies
|
|
||||||
uses: Swatinem/rust-cache@v2
|
|
||||||
with:
|
|
||||||
workspaces: 'src-tauri -> target'
|
|
||||||
cache-on-failure: true
|
|
||||||
|
|
||||||
- name: Install frontend dependencies
|
|
||||||
run: npm install
|
|
||||||
|
|
||||||
- name: Build the app
|
|
||||||
run: npm run tauri build
|
|
||||||
|
|
||||||
- name: Find build assets
|
|
||||||
id: find-assets
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
echo "msi_path=$(find src-tauri/target/release/bundle/msi -name "*.msi" | head -n 1)" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
- name: Upload Windows builds as artifacts
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: windows-builds
|
|
||||||
path: |
|
|
||||||
${{ steps.find-assets.outputs.msi_path }}
|
|
||||||
retention-days: 1
|
|
||||||
|
|
||||||
# Final job to create the release and upload assets
|
|
||||||
publish-release:
|
|
||||||
needs: [version-bump, build-linux]
|
|
||||||
if: ${{ !github.event.inputs.dry_run }}
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Download changelog
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: changelog
|
|
||||||
|
|
||||||
- name: Download Linux builds
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: linux-builds
|
|
||||||
path: dist
|
|
||||||
|
|
||||||
# Add this step if Windows builds are enabled
|
|
||||||
# - name: Download Windows builds
|
|
||||||
# if: needs.build-windows.result == 'success'
|
|
||||||
# uses: actions/download-artifact@v4
|
|
||||||
# with:
|
|
||||||
# name: windows-builds
|
|
||||||
# path: dist
|
|
||||||
|
|
||||||
- name: Check downloaded artifacts
|
|
||||||
run: |
|
|
||||||
echo "Contents of dist directory:"
|
|
||||||
find dist -type f | sort
|
|
||||||
|
|
||||||
- name: Create GitHub Release
|
|
||||||
id: create_release
|
|
||||||
uses: actions/create-release@v1
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
NEW_VERSION: ${{ needs.version-bump.outputs.new_version }}
|
|
||||||
with:
|
|
||||||
tag_name: v${{ needs.version-bump.outputs.new_version }}
|
|
||||||
release_name: CreamLinux v${{ needs.version-bump.outputs.new_version }}
|
|
||||||
body_path: ${{ github.event.inputs.custom_release_notes == '' && 'changelog.md' || github.event.inputs.custom_release_notes }}
|
|
||||||
draft: false
|
|
||||||
prerelease: false
|
|
||||||
|
|
||||||
- name: Get filenames
|
|
||||||
id: get_filenames
|
|
||||||
run: |
|
|
||||||
echo "appimage_filename=$(basename $(find dist -name '*.AppImage' | head -n 1))" >> $GITHUB_OUTPUT
|
|
||||||
echo "deb_filename=$(basename $(find dist -name '*.deb' | head -n 1))" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
- name: Upload AppImage to release
|
|
||||||
uses: actions/upload-release-asset@v1
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
with:
|
|
||||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
|
||||||
asset_path: ./dist/${{ steps.get_filenames.outputs.appimage_filename }}
|
|
||||||
asset_name: CreamLinux-${{ needs.version-bump.outputs.new_version }}.AppImage
|
|
||||||
asset_content_type: application/octet-stream
|
|
||||||
|
|
||||||
- name: Upload Debian Package to release
|
|
||||||
uses: actions/upload-release-asset@v1
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
with:
|
|
||||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
|
||||||
asset_path: ./dist/${{ steps.get_filenames.outputs.deb_filename }}
|
|
||||||
asset_name: creamlinux_${{ needs.version-bump.outputs.new_version }}_amd64.deb
|
|
||||||
asset_content_type: application/vnd.debian.binary-package
|
|
||||||
149
docs/release.md
149
docs/release.md
@@ -1,149 +0,0 @@
|
|||||||
# Release Process for CreamLinux
|
|
||||||
|
|
||||||
This document describes the automated release process for CreamLinux, including version management, changelog generation, and asset publishing.
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
CreamLinux uses GitHub Actions to automate the release process. The workflow handles:
|
|
||||||
|
|
||||||
1. Version incrementing (patch, minor, major)
|
|
||||||
2. Changelog generation from commit messages
|
|
||||||
3. Building release artifacts (AppImage, Debian package)
|
|
||||||
4. Publishing these artifacts to GitHub Releases
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
|
|
||||||
To use the release automation, you need:
|
|
||||||
|
|
||||||
- Git installed locally
|
|
||||||
- GitHub CLI installed and authenticated
|
|
||||||
- Proper GitHub permissions on the repository
|
|
||||||
- Optional: `act` for local testing (https://github.com/nektos/act)
|
|
||||||
|
|
||||||
## Starting a Release
|
|
||||||
|
|
||||||
### Method 1: Using the `npm run release` command (Recommended)
|
|
||||||
|
|
||||||
The easiest way to trigger a release is using the npm script:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# For a patch release (0.1.0 -> 0.1.1)
|
|
||||||
npm run release patch
|
|
||||||
|
|
||||||
# For a minor release (0.1.0 -> 0.2.0)
|
|
||||||
npm run release minor
|
|
||||||
|
|
||||||
# For a major release (0.1.0 -> 2.0.0)
|
|
||||||
npm run release major
|
|
||||||
```
|
|
||||||
|
|
||||||
You can also provide custom release notes:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm run release minor "Added DLC management feature and improved UI"
|
|
||||||
```
|
|
||||||
|
|
||||||
If you don't provide custom notes, they will be automatically generated from commit messages since the last release.
|
|
||||||
|
|
||||||
### Advanced Options
|
|
||||||
|
|
||||||
The release script supports several advanced options:
|
|
||||||
|
|
||||||
#### Dry Run
|
|
||||||
|
|
||||||
Run the release process without actually creating a release:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm run release patch --dry-run
|
|
||||||
```
|
|
||||||
|
|
||||||
This will perform all the version incrementing and workflow steps but won't create the actual GitHub release.
|
|
||||||
|
|
||||||
#### Local Testing
|
|
||||||
|
|
||||||
Test the workflow locally before running it on GitHub:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm run release minor --local
|
|
||||||
```
|
|
||||||
|
|
||||||
This requires the `act` tool to be installed (https://github.com/nektos/act) and runs the workflow locally to check for errors.
|
|
||||||
|
|
||||||
You can combine options:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm run release patch --local --dry-run
|
|
||||||
```
|
|
||||||
|
|
||||||
### Method 2: Manually triggering the workflow in GitHub
|
|
||||||
|
|
||||||
You can also manually trigger the workflow from the GitHub Actions tab:
|
|
||||||
|
|
||||||
1. Go to your repository on GitHub
|
|
||||||
2. Click on the "Actions" tab
|
|
||||||
3. Select the "Release CreamLinux" workflow
|
|
||||||
4. Click "Run workflow"
|
|
||||||
5. Choose the version increment type (patch, minor, major)
|
|
||||||
6. Optionally enter custom release notes
|
|
||||||
7. Check the "dry run" option if you want to test without creating a release
|
|
||||||
8. Click "Run workflow"
|
|
||||||
|
|
||||||
## Release Process Details
|
|
||||||
|
|
||||||
The release process follows these steps:
|
|
||||||
|
|
||||||
1. **Version Calculation**: Determines the new version based on the current version and increment type
|
|
||||||
2. **File Updates**: Updates version numbers in:
|
|
||||||
- `package.json`
|
|
||||||
- `src-tauri/Cargo.toml`
|
|
||||||
- `src-tauri/tauri.conf.json`
|
|
||||||
3. **Changelog Generation**: If no custom notes are provided, generates a changelog from commits
|
|
||||||
4. **Git Operations**:
|
|
||||||
- Commits the version changes
|
|
||||||
- Creates a version tag
|
|
||||||
- Pushes the changes and tag to the repository
|
|
||||||
5. **Build Process**: Builds the application for Linux (and potentially other platforms)
|
|
||||||
6. **Release Creation**: Creates a GitHub Release with the changelog after all builds are complete
|
|
||||||
7. **Asset Upload**: Uploads the AppImage and Debian package to the release
|
|
||||||
|
|
||||||
## Optimizations
|
|
||||||
|
|
||||||
The release workflow includes several optimizations:
|
|
||||||
|
|
||||||
- **Caching**: Uses Rust and npm caches to speed up build times
|
|
||||||
- **Parallel Builds**: Builds for different platforms in parallel
|
|
||||||
- **Artifact Management**: Properly manages build artifacts between jobs
|
|
||||||
- **Error Handling**: Improves error detection and reporting
|
|
||||||
|
|
||||||
## Release Artifacts
|
|
||||||
|
|
||||||
The following artifacts are published to the GitHub release:
|
|
||||||
|
|
||||||
- AppImage (`.AppImage`): Portable Linux executable
|
|
||||||
- Debian Package (`.deb`): For Debian/Ubuntu-based distributions
|
|
||||||
|
|
||||||
## Versioning Convention
|
|
||||||
|
|
||||||
CreamLinux follows [Semantic Versioning](https://semver.org/):
|
|
||||||
|
|
||||||
- **Major version**: Incompatible API changes
|
|
||||||
- **Minor version**: Backwards-compatible functionality
|
|
||||||
- **Patch version**: Backwards-compatible bug fixes
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
If you encounter issues with the release process:
|
|
||||||
|
|
||||||
1. **Check GitHub Actions logs**: Review the workflow logs for detailed error information
|
|
||||||
2. **Use local testing**: Run with `--local` flag to test locally before triggering on GitHub
|
|
||||||
3. **Try dry run mode**: Use `--dry-run` to test the process without creating an actual release
|
|
||||||
4. **Verify permissions**: Ensure you have write permissions to the repository
|
|
||||||
5. **GitHub CLI authentication**: Run `gh auth status` to verify authentication
|
|
||||||
|
|
||||||
Common errors:
|
|
||||||
|
|
||||||
- **"act not found"**: Install the `act` tool for local testing
|
|
||||||
- **Upload errors**: Check if the build produced the expected artifacts
|
|
||||||
- **Permission errors**: Check GitHub permissions and token access
|
|
||||||
|
|
||||||
For technical issues with the release workflow, contact the CreamLinux maintainers.
|
|
||||||
@@ -8,8 +8,7 @@
|
|||||||
"build": "tsc -b && vite build",
|
"build": "tsc -b && vite build",
|
||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"tauri": "tauri",
|
"tauri": "tauri"
|
||||||
"release": "node scripts/release.js"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tauri-apps/api": "^2.5.0",
|
"@tauri-apps/api": "^2.5.0",
|
||||||
|
|||||||
@@ -1,255 +0,0 @@
|
|||||||
#!/usr/bin/env node
|
|
||||||
|
|
||||||
/**
|
|
||||||
* CreamLinux Release Script
|
|
||||||
* This script helps automate the release process by triggering the GitHub Actions workflow
|
|
||||||
*
|
|
||||||
* Usage:
|
|
||||||
* node scripts/release.js [patch|minor|major] [options] [release notes]
|
|
||||||
*
|
|
||||||
* Options:
|
|
||||||
* --dry-run Perform a dry run (no actual release)
|
|
||||||
* --local Test the workflow locally with act before running on GitHub
|
|
||||||
* --help Show help message
|
|
||||||
*
|
|
||||||
* Examples:
|
|
||||||
* node scripts/release.js patch
|
|
||||||
* node scripts/release.js minor "Added new feature X"
|
|
||||||
* node scripts/release.js major "Major redesign with new UI"
|
|
||||||
* node scripts/release.js patch --dry-run
|
|
||||||
* node scripts/release.js minor --local
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { execSync } from 'child_process'
|
|
||||||
import { existsSync } from 'fs'
|
|
||||||
import path from 'path'
|
|
||||||
|
|
||||||
// Configuration
|
|
||||||
const GITHUB_WORKFLOW_NAME = 'release.yml'
|
|
||||||
|
|
||||||
// Check if act is installed for local testing
|
|
||||||
function isActInstalled() {
|
|
||||||
try {
|
|
||||||
execSync('act --version', { stdio: 'ignore' })
|
|
||||||
return true
|
|
||||||
} catch (error) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate environment
|
|
||||||
function validateEnvironment(isLocal) {
|
|
||||||
try {
|
|
||||||
// Check if git is installed
|
|
||||||
execSync('git --version', { stdio: 'ignore' })
|
|
||||||
|
|
||||||
if (!isLocal) {
|
|
||||||
// Check if GitHub CLI is installed
|
|
||||||
execSync('gh --version', { stdio: 'ignore' })
|
|
||||||
|
|
||||||
// Check if the user is authenticated with GitHub CLI
|
|
||||||
execSync('gh auth status', { stdio: 'ignore' })
|
|
||||||
} else {
|
|
||||||
// Check if act is installed for local testing
|
|
||||||
if (!isActInstalled()) {
|
|
||||||
console.error('Error: "act" is required for local testing but is not installed.')
|
|
||||||
console.error('You can install it from: https://github.com/nektos/act')
|
|
||||||
process.exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if we're in a git repository
|
|
||||||
execSync('git rev-parse --is-inside-work-tree', { stdio: 'ignore' })
|
|
||||||
|
|
||||||
// Check if the workflow file exists
|
|
||||||
const workflowPath = path.join('.github', 'workflows', GITHUB_WORKFLOW_NAME)
|
|
||||||
if (!existsSync(workflowPath)) {
|
|
||||||
console.error(`Error: Workflow file not found at ${workflowPath}`)
|
|
||||||
process.exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if there are uncommitted changes
|
|
||||||
const status = execSync('git status --porcelain').toString().trim()
|
|
||||||
if (status) {
|
|
||||||
console.error('Error: There are uncommitted changes in the repository.')
|
|
||||||
console.error('Please commit or stash your changes before running this script.')
|
|
||||||
process.exit(1)
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`Environment validation failed: ${error.message}`)
|
|
||||||
process.exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse arguments
|
|
||||||
function parseArguments() {
|
|
||||||
const args = process.argv.slice(2)
|
|
||||||
|
|
||||||
if (args.length === 0 || args[0] === '--help') {
|
|
||||||
showUsage()
|
|
||||||
process.exit(args[0] === '--help' ? 0 : 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
const versionType = args[0].toLowerCase()
|
|
||||||
if (!['patch', 'minor', 'major'].includes(versionType)) {
|
|
||||||
console.error(`Error: Invalid version type "${versionType}"`)
|
|
||||||
showUsage()
|
|
||||||
process.exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract options
|
|
||||||
const options = {
|
|
||||||
dryRun: args.includes('--dry-run'),
|
|
||||||
localTest: args.includes('--local'),
|
|
||||||
}
|
|
||||||
|
|
||||||
// Join remaining arguments as release notes (excluding options)
|
|
||||||
const releaseNotes = args
|
|
||||||
.slice(1)
|
|
||||||
.filter((arg) => !arg.startsWith('--'))
|
|
||||||
.join(' ')
|
|
||||||
|
|
||||||
return { versionType, releaseNotes, options }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show usage information
|
|
||||||
function showUsage() {
|
|
||||||
console.log('Usage: node scripts/release.js [patch|minor|major] [options] [release notes]')
|
|
||||||
console.log('')
|
|
||||||
console.log('Options:')
|
|
||||||
console.log(' --dry-run Perform a dry run (no actual release)')
|
|
||||||
console.log(' --local Test the workflow locally with act before running on GitHub')
|
|
||||||
console.log(' --help Show this help message')
|
|
||||||
console.log('')
|
|
||||||
console.log('Examples:')
|
|
||||||
console.log(' node scripts/release.js patch')
|
|
||||||
console.log(' node scripts/release.js minor "Added new feature X"')
|
|
||||||
console.log(' node scripts/release.js major "Major redesign with new UI"')
|
|
||||||
console.log(' node scripts/release.js patch --dry-run')
|
|
||||||
console.log(' node scripts/release.js minor --local')
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run local test with act
|
|
||||||
function runLocalTest(versionType, releaseNotes) {
|
|
||||||
console.log('\n=== Running local workflow test with act ===')
|
|
||||||
|
|
||||||
try {
|
|
||||||
const actCommand = `act workflow_dispatch -j version-bump -e ./scripts/test-event.json`
|
|
||||||
|
|
||||||
// First create the test event JSON
|
|
||||||
const testEvent = {
|
|
||||||
inputs: {
|
|
||||||
version_type: versionType,
|
|
||||||
custom_release_notes: releaseNotes || '',
|
|
||||||
dry_run: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write the test event to a file
|
|
||||||
const fs = require('fs')
|
|
||||||
fs.writeFileSync('./scripts/test-event.json', JSON.stringify(testEvent, null, 2))
|
|
||||||
|
|
||||||
console.log('Running local test with act (this might take a while)...')
|
|
||||||
execSync(actCommand, { stdio: 'inherit' })
|
|
||||||
|
|
||||||
// Clean up
|
|
||||||
fs.unlinkSync('./scripts/test-event.json')
|
|
||||||
|
|
||||||
console.log('\n✅ Local test completed successfully!')
|
|
||||||
return true
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`❌ Local test failed: ${error.message}`)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trigger GitHub workflow
|
|
||||||
function triggerWorkflow(versionType, releaseNotes, isDryRun) {
|
|
||||||
try {
|
|
||||||
console.log(
|
|
||||||
`Triggering release workflow with version type: ${versionType}${isDryRun ? ' (dry run)' : ''}`
|
|
||||||
)
|
|
||||||
|
|
||||||
let command = `gh workflow run ${GITHUB_WORKFLOW_NAME} -f version_type=${versionType} -f dry_run=${isDryRun}`
|
|
||||||
|
|
||||||
if (releaseNotes) {
|
|
||||||
command += ` -f custom_release_notes="${releaseNotes}"`
|
|
||||||
}
|
|
||||||
|
|
||||||
execSync(command, { stdio: 'inherit' })
|
|
||||||
|
|
||||||
console.log('\n✅ Release workflow triggered successfully!')
|
|
||||||
console.log('You can check the progress in the Actions tab of your GitHub repository.')
|
|
||||||
console.log('https://github.com/yourusername/creamlinux/actions')
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`❌ Failed to trigger workflow: ${error.message}`)
|
|
||||||
process.exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Main function
|
|
||||||
async function main() {
|
|
||||||
console.log('=== CreamLinux Release Script ===\n')
|
|
||||||
|
|
||||||
const { versionType, releaseNotes, options } = parseArguments()
|
|
||||||
|
|
||||||
// Validate environment based on mode
|
|
||||||
validateEnvironment(options.localTest)
|
|
||||||
|
|
||||||
console.log(`Version type: ${versionType} (${options.dryRun ? 'dry run' : 'actual release'})`)
|
|
||||||
if (releaseNotes) {
|
|
||||||
console.log(`Release notes: "${releaseNotes}"`)
|
|
||||||
} else {
|
|
||||||
console.log('Release notes: Auto-generated from commit messages')
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.localTest) {
|
|
||||||
// Run local test first
|
|
||||||
const success = runLocalTest(versionType, releaseNotes)
|
|
||||||
|
|
||||||
if (options.localTest) {
|
|
||||||
// Run local test first
|
|
||||||
const success = runLocalTest(versionType, releaseNotes)
|
|
||||||
|
|
||||||
if (!success) {
|
|
||||||
console.error('\nLocal test failed. Fix the issues before running on GitHub.')
|
|
||||||
process.exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// If it was just a local test, exit here
|
|
||||||
if (options.dryRun) {
|
|
||||||
console.log(
|
|
||||||
'\nLocal test completed successfully. Exiting without triggering GitHub workflow.'
|
|
||||||
)
|
|
||||||
process.exit(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ask if user wants to continue with actual GitHub workflow
|
|
||||||
console.log('\nLocal test passed! Do you want to trigger the actual GitHub workflow?')
|
|
||||||
console.log('Press Ctrl+C to cancel or wait 5 seconds to continue...')
|
|
||||||
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
triggerWorkflow(versionType, releaseNotes, options.dryRun)
|
|
||||||
resolve()
|
|
||||||
}, 5000)
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
// No local test, just confirm and trigger workflow
|
|
||||||
console.log('\nThis will trigger a GitHub Actions workflow to create a new release.')
|
|
||||||
console.log('Press Ctrl+C to cancel or wait 5 seconds to continue...')
|
|
||||||
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
triggerWorkflow(versionType, releaseNotes, options.dryRun)
|
|
||||||
resolve()
|
|
||||||
}, 5000)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
main().catch((err) => {
|
|
||||||
console.error(err)
|
|
||||||
process.exit(1)
|
|
||||||
})
|
|
||||||
Reference in New Issue
Block a user