Merge pull request #55 from lumpinif/main #13
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: chrome-extension CI | |
on: | |
push: | |
branches: [main] | |
paths: | |
- "extensions/chrome/**" | |
pull_request: | |
branches: [main] | |
paths: | |
- "extensions/chrome/**" | |
defaults: | |
run: | |
working-directory: ./extensions/chrome | |
jobs: | |
lint-and-format: | |
runs-on: ubuntu-latest | |
permissions: | |
contents: write | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
token: ${{ secrets.GITHUB_TOKEN }} | |
- name: Setup Bun | |
uses: oven-sh/setup-bun@v1 | |
with: | |
bun-version: latest | |
- name: Install dependencies | |
run: bun install | |
- name: Run ESLint and format fix | |
run: bun run fix | |
- name: Run markdown lint | |
# DON't TOUCH THIS LINE BELOW # | |
run: bunx markdownlint-cli2 "./**/*.md" --config .markdownlint-cli2.jsonc | |
test-and-build: | |
needs: lint-and-format | |
runs-on: ubuntu-latest | |
permissions: | |
contents: write | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Setup Bun | |
uses: oven-sh/setup-bun@v1 | |
with: | |
bun-version: latest | |
- name: Install dependencies | |
run: bun install | |
- name: Run tests | |
run: bun test | |
- name: Build extension | |
run: bun run build | |
# Automatically increments the patch version (e.g., 1.0.0 -> 1.0.1) | |
# and creates a release | |
# Only increment patch version for non-major versions | |
- name: Check existing tag | |
id: check_tag | |
shell: bash | |
run: | | |
set -euo pipefail # Exit on error, undefined vars, and pipe failures | |
# Function to validate semver format | |
# Supports standard versions (x.y.z) and pre-release versions (x.y.z-beta.n) | |
validate_version() { | |
local version="$1" | |
if ! [[ "$version" =~ ^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-((0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*)(\.(0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*))*))?(\+([0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*))?$ ]]; then | |
echo "Error: Invalid version format: $version" | |
echo "Version must be in format: x.y.z or x.y.z-pre.n" | |
exit 1 | |
fi | |
} | |
# Function to update version in JSON files | |
update_json_version() { | |
local file="$1" | |
local cur_ver="$2" | |
local new_ver="$3" | |
if [[ ! -f "$file" ]]; then | |
echo "Error: File $file not found" | |
exit 1 | |
fi | |
# Check if version field exists | |
if ! grep -q "\"version\":" "$file"; then | |
echo "Error: No version field found in $file" | |
exit 1 | |
fi | |
# Backup file before modification | |
cp "$file" "${file}.bak" | |
if ! sed -i "s/\"version\": \"$cur_ver\"/\"version\": \"$new_ver\"/" "$file"; then | |
echo "Error: Failed to update version in $file" | |
mv "${file}.bak" "$file" # Restore backup | |
exit 1 | |
fi | |
rm "${file}.bak" # Remove backup if successful | |
} | |
# Function to compare versions | |
version_gt() { | |
test "$(echo "$@" | tr " " "\n" | sort -V | head -n 1)" != "$1" | |
} | |
# Get current version with error handling | |
if [[ ! -f "package.json" ]]; then | |
echo "Error: package.json not found" | |
exit 1 | |
fi | |
if ! current_version=$(node -p "try { require('./package.json').version } catch(e) { console.error(e); process.exit(1) }" 2>/dev/null); then | |
echo "Error: Failed to read version from package.json" | |
exit 1 | |
fi | |
# Validate version format | |
validate_version "$current_version" | |
# Get highest existing version with error handling | |
if ! highest_version=$(git ls-remote --tags origin | grep "refs/tags/chrome-extension-v" | sed 's/.*chrome-extension-v//' | sort -V | tail -n 1); then | |
echo "Warning: Failed to fetch remote tags, proceeding with caution" | |
fi | |
# Prevent version downgrade | |
# Note: To downgrade versions, you need to manually: | |
# 1. Delete the higher version tag: git push origin :refs/tags/chrome-extension-v<version> | |
# 2. Delete the corresponding GitHub release | |
if [ ! -z "$highest_version" ] && version_gt "$highest_version" "$current_version"; then | |
echo "Error: Version downgrade not allowed. Current: $current_version, Highest: $highest_version" | |
exit 1 | |
fi | |
# Handle pre-release versions | |
if [[ "$current_version" == *"-"* ]]; then | |
echo "Pre-release version detected: $current_version" | |
# Extract base version and pre-release parts | |
base_version=${current_version%%-*} | |
pre_release=${current_version#*-} | |
pre_type=${pre_release%%.*} | |
pre_num=${pre_release#*.} | |
# Check if same pre-release version exists | |
if git ls-remote --tags origin | grep -q "refs/tags/chrome-extension-v$current_version"; then | |
# Increment pre-release number | |
new_pre_num=$((pre_num + 1)) | |
new_version="${base_version}-${pre_type}.${new_pre_num}" | |
echo "Incrementing pre-release: $current_version -> $new_version" | |
echo "version=$new_version" >> $GITHUB_OUTPUT | |
echo "version_changed=true" >> $GITHUB_OUTPUT | |
else | |
echo "Using current pre-release version: $current_version" | |
echo "version=$current_version" >> $GITHUB_OUTPUT | |
echo "version_changed=false" >> $GITHUB_OUTPUT | |
fi | |
exit 0 | |
fi | |
# Handle major versions (x.0.0) | |
if [[ "$current_version" =~ ^[0-9]+\.0\.0$ ]]; then | |
echo "Major version detected: $current_version" | |
# Check if major version tag exists | |
if git ls-remote --tags origin | grep -q "refs/tags/chrome-extension-v$current_version"; then | |
# Increment patch version like normal | |
new_version="${current_version%.*}.1" # x.0.0 -> x.0.1 | |
echo "Major version exists, incrementing patch: $current_version -> $new_version" | |
echo "version=$new_version" >> $GITHUB_OUTPUT | |
echo "version_changed=true" >> $GITHUB_OUTPUT | |
else | |
echo "Using new major version: $current_version" | |
echo "version=$current_version" >> $GITHUB_OUTPUT | |
echo "version_changed=false" >> $GITHUB_OUTPUT | |
fi | |
exit 0 | |
fi | |
# Check if tag exists | |
if git ls-remote --tags origin | grep -q "refs/tags/chrome-extension-v$current_version"; then | |
echo "Tag exists, incrementing patch version" | |
# Split version into components | |
IFS='.' read -r major minor patch <<< "$current_version" | |
new_version="$major.$minor.$((patch + 1))" | |
validate_version "$new_version" | |
echo "Updating version from $current_version to $new_version" | |
# Update version in files | |
update_json_version "package.json" "$current_version" "$new_version" | |
update_json_version "public/manifest.json" "$current_version" "$new_version" | |
# Configure git for fork workflow | |
git config --global user.email "github-actions[bot]@users.noreply.github.com" | |
git config --global user.name "github-actions[bot]" | |
# Commit and push changes | |
git add package.json public/manifest.json | |
git commit -m "chore: bump version to $new_version [skip ci]" | |
if ! git push; then | |
echo "Error: Failed to push changes" | |
exit 1 | |
fi | |
echo "version=$new_version" >> $GITHUB_OUTPUT | |
echo "version_changed=true" >> $GITHUB_OUTPUT | |
else | |
echo "Using current version: $current_version" | |
echo "version=$current_version" >> $GITHUB_OUTPUT | |
echo "version_changed=false" >> $GITHUB_OUTPUT | |
fi | |
- name: Zip Extension | |
run: zip -r thinking-claude-chrome-extension-v${{ steps.check_tag.outputs.version }}.zip dist/ | |
- name: Create Release | |
if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
uses: softprops/action-gh-release@v1 | |
with: | |
name: Chrome Extension v${{ steps.check_tag.outputs.version }} | |
tag_name: chrome-extension-v${{ steps.check_tag.outputs.version }} | |
files: extensions/chrome/thinking-claude-chrome-extension-v${{ steps.check_tag.outputs.version }}.zip | |
generate_release_notes: true | |
token: ${{ secrets.GITHUB_TOKEN }} | |
fail_on_unmatched_files: true |