Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: Release

on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
tag:
description: 'Existing tag to release (e.g. v1.4.0)'
required: true
type: string

permissions:
contents: read

jobs:
release:
name: Create GitHub Release
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Determine tag
id: tag
env:
INPUT_TAG: ${{ inputs.tag }}
REF_NAME: ${{ github.ref_name }}
run: |
TAG="${INPUT_TAG:-$REF_NAME}"
case "$TAG" in
v[0-9]*.[0-9]*.[0-9]*) ;;
*) echo "Not a release tag: $TAG"; exit 1 ;;
esac
echo "tag=$TAG" >> "$GITHUB_OUTPUT"

- name: Checkout tag
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
ref: ${{ steps.tag.outputs.tag }}

- name: Extract changelog section
env:
TAG: ${{ steps.tag.outputs.tag }}
run: |
VERSION="${TAG#v}"
awk -v ver="$VERSION" '
index($0, "## [" ver "]") == 1 { found = 1; next }
found && /^## \[/ { exit }
found { print }
' CHANGELOG.md > release-notes.md
if [ ! -s release-notes.md ]; then
echo "No CHANGELOG.md section found for version $VERSION"
exit 1
fi

- name: Create GitHub Release
env:
GH_TOKEN: ${{ github.token }}
TAG: ${{ steps.tag.outputs.tag }}
run: |
gh release create "$TAG" \
--verify-tag \
--title "$TAG" \
--notes-file release-notes.md
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Excel exports of RTL documents open with a right-to-left sheet view, and the data preview lays out right-to-left for RTL documents
- "Include Headers" now adds an Excel autofilter to the header row, making the exported sheet filterable
- Fully bilingual status messages: progress, errors, file info, page count, and column labels now follow the selected language
- Footer now shows the GitHub logo linking to the source repository and an Apache License 2.0 notice (bilingual)
- Release workflow (`.github/workflows/release.yml`): pushing a `v*` tag (or a manual dispatch) creates the GitHub Release with the matching CHANGELOG section as notes

### Changed

Expand All @@ -24,6 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Cleanup options (Skip Empty Rows, Merge Fragments, Auto-detect Columns) are now non-destructive: unchecking an option restores the original extracted data
- Turnstile verification is required once per session instead of once per file
- "Hebrew/Arabic RTL Support" is now enabled by default (it only activates on documents detected as RTL)
- `scripts/release.sh` reworked for the PR-based flow: it now only validates and pushes the version tag (the version bump and CHANGELOG entry come from the PR, the GitHub Release comes from the release workflow)

### Fixed

Expand Down
3 changes: 3 additions & 0 deletions public/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -1135,6 +1135,7 @@ const translations = {
footerLink2: "NX1X Lab",
footerLink3: "GitHub",
footerPrivacy: "<strong>Privacy:</strong> Your PDFs are processed entirely in your browser. No files are uploaded to any server. Anonymous usage analytics via Cloudflare Analytics.",
footerLicense: 'Open source under the <a href="https://github.com/NX1X/EasyConvert/blob/main/LICENSE" target="_blank" rel="noopener">Apache License 2.0</a>',
footerCopyright: `© ${currentYear} NX1X.`,
statusVerify: "Please complete the security verification below to proceed.",
statusLoading: "Loading PDF file...",
Expand Down Expand Up @@ -1194,6 +1195,7 @@ const translations = {
footerLink2: "NX1X Lab",
footerLink3: "GitHub",
footerPrivacy: "<strong>פרטיות:</strong> קבצי ה-PDF שלכם מעובדים לחלוטין בדפדפן שלכם. לא מועלים קבצים לשום שרת. אנליטיקה אנונימית בסיסית דרך Cloudflare Analytics.",
footerLicense: 'קוד פתוח תחת <a href="https://github.com/NX1X/EasyConvert/blob/main/LICENSE" target="_blank" rel="noopener">רישיון Apache 2.0</a>',
footerCopyright: `© ${currentYear} NX1X.`,
statusVerify: "אנא השלימו את אימות האבטחה למטה כדי להמשיך.",
statusLoading: "טוען קובץ PDF...",
Expand Down Expand Up @@ -1289,6 +1291,7 @@ function updateLanguage() {
updateElement('footerLink2', lang.footerLink2);
updateElement('footerLink3', lang.footerLink3);
updateElement('footerPrivacy', lang.footerPrivacy, true);
updateElement('footerLicense', lang.footerLicense, true);
updateElement('footerCopyright', lang.footerCopyright);

const customRangeInput = document.getElementById('customRange');
Expand Down
9 changes: 8 additions & 1 deletion public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -339,13 +339,20 @@ <h3 id="shareTitle">Found EasyConvert helpful?</h3>
<div class="footer-links">
<a href="https://nx1xlab.dev/nxtools" target="_blank" rel="noopener" class="footer-link" id="footerLink1">More NX Tools</a>
<a href="https://nx1xlab.dev" target="_blank" rel="noopener" class="footer-link" id="footerLink2">NX1X Lab</a>
<a href="https://github.com/NX1X/EasyConvert" target="_blank" rel="noopener" class="footer-link" id="footerLink3">GitHub</a>
<a href="https://github.com/NX1X/EasyConvert" target="_blank" rel="noopener" class="footer-link footer-github-link">
<svg class="footer-github-icon" viewBox="0 0 24 24" width="18" height="18" aria-hidden="true"><path fill="currentColor" d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0 0 24 12c0-6.63-5.37-12-12-12z"/></svg>
<span id="footerLink3">GitHub</span>
</a>
</div>

<div class="footer-privacy" id="footerPrivacy">
<strong>Privacy:</strong> Your PDFs are processed entirely in your browser. No files are uploaded to any server. Anonymous usage analytics via Cloudflare Analytics.
</div>

<div class="footer-license" id="footerLicense">
Open source under the <a href="https://github.com/NX1X/EasyConvert/blob/main/LICENSE" target="_blank" rel="noopener">Apache License 2.0</a>
</div>

<div class="footer-copyright" id="footerCopyright">
&copy; NX1X.
</div>
Expand Down
21 changes: 21 additions & 0 deletions public/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,27 @@ body {
margin-bottom: 20px;
}

.footer-github-link {
display: inline-flex;
align-items: center;
gap: 6px;
}

.footer-github-icon {
flex-shrink: 0;
}

.footer-license {
font-size: 0.85rem;
opacity: 0.8;
margin-bottom: 12px;
}

.footer-license a {
color: white;
text-decoration: underline;
}

.footer-copyright {
font-size: 0.85rem;
opacity: 0.7;
Expand Down
158 changes: 31 additions & 127 deletions scripts/release.sh
Original file line number Diff line number Diff line change
@@ -1,145 +1,49 @@
#!/bin/bash
#!/usr/bin/env bash

# EasyConvert Release Script
# Automates version bumping and release process
# EasyConvert release script.
#
# The version bump and CHANGELOG entry land on main through a normal PR
# (package.json, README badge, sw.js CACHE_NAME, CHANGELOG.md). This script
# then tags that version and pushes the tag; the GitHub Release itself is
# created by .github/workflows/release.yml, which uses the matching
# CHANGELOG.md section as the release notes.

set -e # Exit on any error
set -euo pipefail

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
REPO_URL="https://github.com/NX1X/EasyConvert"

# Function to print colored output
print_status() {
echo -e "${BLUE}[INFO]${NC} $1"
}
fail() { echo "ERROR: $1" >&2; exit 1; }

print_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
git rev-parse --git-dir > /dev/null 2>&1 || fail "Not in a git repository."

print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
BRANCH=$(git rev-parse --abbrev-ref HEAD)
[ "$BRANCH" = "main" ] || fail "Releases are tagged from main (currently on '$BRANCH')."

print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
[ -z "$(git status --porcelain)" ] || fail "Working tree is not clean. Commit or stash first."

# Check if we're in a git repository
if ! git rev-parse --git-dir > /dev/null 2>&1; then
print_error "Not in a git repository!"
exit 1
fi

# Check if there are uncommitted changes
if [[ -n $(git status --porcelain) ]]; then
print_warning "You have uncommitted changes. Please commit or stash them first."
git status --short
exit 1
fi

# Parse arguments
if [[ $# -lt 1 ]]; then
echo "Usage: $0 <patch|minor|major|version> [release-notes]"
echo ""
echo "Examples:"
echo " $0 patch \"Fixed table detection bug\""
echo " $0 minor \"Added new export format\""
echo " $0 major \"Complete UI redesign\""
echo " $0 1.2.3 \"Custom version with release notes\""
exit 1
fi
git fetch origin main --tags
[ "$(git rev-parse HEAD)" = "$(git rev-parse origin/main)" ] || \
fail "Local main is not in sync with origin/main. Pull or push first."

BUMP_TYPE=$1
RELEASE_NOTES=${2:-"Version bump"}
VERSION=$(node -p "require('./package.json').version")
TAG="v$VERSION"

# Get current version from package.json
CURRENT_VERSION=$(node -p "require('./package.json').version")
print_status "Current version: $CURRENT_VERSION"
grep -q "^## \[$VERSION\]" CHANGELOG.md || \
fail "CHANGELOG.md has no '## [$VERSION]' section. Add it before releasing."

# Calculate new version
if [[ $BUMP_TYPE =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
# Custom version provided
NEW_VERSION=$BUMP_TYPE
else
# Calculate based on bump type
IFS='.' read -ra VERSION_PARTS <<< "$CURRENT_VERSION"
MAJOR=${VERSION_PARTS[0]}
MINOR=${VERSION_PARTS[1]}
PATCH=${VERSION_PARTS[2]}

case $BUMP_TYPE in
"patch")
PATCH=$((PATCH + 1))
;;
"minor")
MINOR=$((MINOR + 1))
PATCH=0
;;
"major")
MAJOR=$((MAJOR + 1))
MINOR=0
PATCH=0
;;
*)
print_error "Invalid bump type: $BUMP_TYPE"
exit 1
;;
esac

NEW_VERSION="$MAJOR.$MINOR.$PATCH"
if git rev-parse "$TAG" > /dev/null 2>&1; then
fail "Tag $TAG already exists."
fi

print_status "New version: $NEW_VERSION"

# Confirm the release
echo ""
print_warning "About to release version $NEW_VERSION"
print_status "Release notes: $RELEASE_NOTES"
echo ""
echo "About to tag and push $TAG (version from package.json)."
read -p "Continue? (y/N): " -n 1 -r
echo ""
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
print_status "Release cancelled."
exit 0
fi

# Update version using Node.js script
print_status "Updating version files..."
if [[ -f "scripts/update-version.js" ]]; then
node scripts/update-version.js "$NEW_VERSION" "$RELEASE_NOTES"
else
print_error "Version update script not found!"
exit 1
fi

# Commit changes
print_status "Committing version changes..."
git add .
git commit -m "Release v$NEW_VERSION

$RELEASE_NOTES"

# Create and push tag
print_status "Creating git tag v$NEW_VERSION..."
git tag -a "v$NEW_VERSION" -m "Release v$NEW_VERSION

$RELEASE_NOTES"

# Push changes and tags
print_status "Pushing to remote repository..."
git push origin main
git push origin "v$NEW_VERSION"
[[ $REPLY =~ ^[Yy]$ ]] || { echo "Cancelled."; exit 0; }

print_success "Successfully released version $NEW_VERSION!"
print_status "🎉 Release completed! Version $NEW_VERSION is now live."
print_status "📝 Changelog updated with release notes"
print_status "🏷️ Git tag v$NEW_VERSION created and pushed"
print_status "🚀 All changes pushed to remote repository"
git tag -a "$TAG" -m "Release $TAG"
git push origin "$TAG"

echo ""
print_status "View your release at: https://github.com/nx1xlab/easyconvert/releases/tag/v$NEW_VERSION"
echo "Tag $TAG pushed. The release workflow is creating the GitHub Release:"
echo " $REPO_URL/actions/workflows/release.yml"
echo " $REPO_URL/releases/tag/$TAG"
Loading