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
5 changes: 5 additions & 0 deletions .changeset/all-times-cut.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"mpesa2csv": minor
---

feat: Replace PDF.js with Tabula for improved PDF table extraction
119 changes: 43 additions & 76 deletions .github/workflows/main-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,6 @@ on:
- patch
- minor
- major
include_android:
description: "Include Android build in this release"
required: false
default: true
type: boolean

concurrency:
group: main-release
Expand Down Expand Up @@ -188,7 +183,7 @@ jobs:
run: |
echo "📦 Installing system dependencies for validation..."
sudo apt-get update
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libglib2.0-dev
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libglib2.0-dev curl wget unzip
echo "✅ System dependencies installed"

- name: Run comprehensive validation
Expand Down Expand Up @@ -243,7 +238,16 @@ jobs:
VALIDATION_PASSED="false"
fi

# 7. Check Rust/Cargo configuration
# 7. Setup JRE for Tabula (required for Rust build)
echo "🔧 Setting up JRE for Tabula..."
if ! bash src-tauri/scripts/setup-build-jre.sh; then
VALIDATION_ERRORS="${VALIDATION_ERRORS}JRE setup failed. "
VALIDATION_PASSED="false"
else
echo "✅ JRE setup completed"
fi

# 8. Check Rust/Cargo configuration
echo "🦀 Validating Rust configuration..."
cd src-tauri

Expand Down Expand Up @@ -297,6 +301,7 @@ jobs:
title: "chore: release version packages"
commit: "chore: release version packages"
createGithubReleases: false
cwd: app
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Expand Down Expand Up @@ -333,6 +338,7 @@ jobs:
pnpm run sync-versions

# Check if there are any changes to commit
cd ..
if ! git diff --quiet; then
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
Expand All @@ -347,12 +353,14 @@ jobs:
- name: Get version and create tag
id: version
run: |
cd app
VERSION=$(node -p "require('./package.json').version")
TAG="v$VERSION"

echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "tag=$TAG" >> $GITHUB_OUTPUT

cd ..
# Configure git
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
Expand All @@ -373,23 +381,11 @@ jobs:
echo "ℹ️ Tag $TAG already exists locally"
fi

# Step 5: Build Android (if requested)
build-android:
name: "Build Android"
needs: [check-release, pre-release-validation, prepare-release]
if: needs.check-release.outputs.should_release == 'true' && needs.pre-release-validation.outputs.validation_passed == 'true' && (github.event.inputs.include_android == 'true' || github.event.inputs.include_android == null)
uses: ./.github/workflows/android-release.yml
with:
version: ${{ needs.prepare-release.outputs.version }}
force_build: true
secrets: inherit

# Step 6: Build and release desktop
# Step 5: Build and release desktop
build-and-release:
name: "Build & Release"
needs:
[check-release, pre-release-validation, prepare-release, build-android]
if: needs.check-release.outputs.should_release == 'true' && needs.pre-release-validation.outputs.validation_passed == 'true' && always() && (needs.build-android.result == 'success' || needs.build-android.result == 'skipped')
needs: [check-release, pre-release-validation, prepare-release]
if: needs.check-release.outputs.should_release == 'true' && needs.pre-release-validation.outputs.validation_passed == 'true'
permissions:
contents: write
strategy:
Expand Down Expand Up @@ -434,7 +430,7 @@ jobs:
if: matrix.platform == 'ubuntu-22.04'
run: |
sudo apt-get update
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf curl wget unzip

- name: Install create-dmg (macOS)
if: matrix.platform == 'macos-latest'
Expand Down Expand Up @@ -492,7 +488,7 @@ jobs:
uses: actions/cache@v4
with:
path: |
node_modules
app/node_modules
key: ${{ runner.os }}-node-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-node-
Expand All @@ -501,25 +497,42 @@ jobs:
uses: actions/cache@v4
with:
path: |
dist
src-tauri/target/release
app/dist
app/src-tauri/target/release
key: ${{ runner.os }}-${{ matrix.build_name }}-build-${{ hashFiles('**/package.json', '**/Cargo.toml', '**/src/**') }}
restore-keys: |
${{ runner.os }}-${{ matrix.build_name }}-build-

- name: Cache JRE for Tabula
uses: actions/cache@v4
with:
path: |
app/src-tauri/resources/build-jre
key: ${{ runner.os }}-${{ matrix.target }}-jre-${{ hashFiles('app/src-tauri/scripts/setup-build-jre.sh') }}
restore-keys: |
${{ runner.os }}-${{ matrix.target }}-jre-

- name: Install frontend dependencies
run: pnpm install --frozen-lockfile

- name: Build frontend
run: pnpm build

- name: Setup JRE for Tabula
shell: bash
run: |
echo "🔧 Setting up JRE for Tabula PDF processing..."
bash src-tauri/scripts/setup-build-jre.sh
echo "✅ JRE setup completed"

- name: Extract changelog for release
id: changelog
shell: bash
continue-on-error: false
run: |
set +e # Disable exit on error for this script
VERSION="${{ needs.prepare-release.outputs.version }}"
cd app

if [ -f "CHANGELOG.md" ]; then
# Extract the changelog section for the current version
Expand Down Expand Up @@ -637,14 +650,6 @@ jobs:
id: timestamp
run: echo "build_time=$(date -u +"%Y-%m-%d %H:%M UTC")" >> $GITHUB_OUTPUT

- name: Download Android artifacts (if available)
if: needs.build-android.result == 'success'
uses: actions/download-artifact@v4
with:
name: mpesa2csv-v${{ needs.prepare-release.outputs.version }}
path: ./android-artifacts/
continue-on-error: true

- name: Build and release Tauri app
id: tauri-action
continue-on-error: true
Expand Down Expand Up @@ -723,22 +728,20 @@ jobs:
| **macOS** | Intel x64 | [📥 Download .dmg](https://github.com/DavidAmunga/mpesa2csv/releases/download/${{ needs.prepare-release.outputs.tag }}/mpesa2csv_${{ needs.prepare-release.outputs.version }}_x64.dmg) | Open DMG and drag to Applications |
| **Linux** | x64 (Ubuntu/Debian) | [📥 Download .deb](https://github.com/DavidAmunga/mpesa2csv/releases/download/${{ needs.prepare-release.outputs.tag }}/mpesa2csv_${{ needs.prepare-release.outputs.version }}_amd64.deb) | `sudo dpkg -i mpesa2csv_*.deb` |
| **Linux** | x64 (Portable) | [📥 Download .AppImage](https://github.com/DavidAmunga/mpesa2csv/releases/download/${{ needs.prepare-release.outputs.tag }}/mpesa2csv_${{ needs.prepare-release.outputs.version }}_amd64.AppImage) | `chmod +x mpesa2csv_*.AppImage && ./mpesa2csv_*.AppImage` |
${{ needs.build-android.result == 'success' && format('| **Android** | ARM64 | [📥 Download .apk](https://github.com/DavidAmunga/mpesa2csv/releases/download/{0}/mpesa2csv-v{1}-universal-release.apk) | Enable "Install from unknown sources" and install', needs.prepare-release.outputs.tag, needs.prepare-release.outputs.version) || '' }}

### 📊 Release Metadata

- **Version**: `${{ needs.prepare-release.outputs.version }}`
- **Build Date**: `${{ steps.timestamp.outputs.build_time }}`
- **Total Changes**: ${{ steps.changelog.outputs.total_changes }}
- **Platforms**: Windows, macOS (Intel + Apple Silicon), Linux${{ needs.build-android.result == 'success' && ', Android' || '' }}
- **Platforms**: Windows, macOS (Intel + Apple Silicon), Linux
${{ steps.changelog.outputs.breaking > 0 && format('- **Breaking Changes**: {0}', steps.changelog.outputs.breaking) || '' }}

### 🔍 System Requirements

- **Windows**: Windows 10 version 1903 or later
- **macOS**: macOS 10.15 Catalina or later
- **Linux**: Modern distribution with GTK 3.24+ and WebKit2GTK 4.1+
${{ needs.build-android.result == 'success' && '- **Android**: Android 7.0 (API level 24) or later' || '' }}

### 🔄 Auto-Update

Expand All @@ -752,38 +755,7 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Upload Android artifacts to release
if: needs.build-android.result == 'success' && matrix.platform == 'ubuntu-22.04'
run: |
if [ -d "./android-artifacts" ]; then
echo "📱 Uploading Android artifacts to release..."
# Move Android artifacts to current directory for upload
find ./android-artifacts -name "*.apk" -o -name "*.aab" | while read file; do
if [ -f "$file" ]; then
filename=$(basename "$file")
cp "$file" "./$filename"
echo "✅ Prepared $filename for release"
fi
done

# Upload to GitHub release using gh CLI
if command -v gh &> /dev/null; then
for file in *.apk *.aab; do
if [ -f "$file" ]; then
echo "📤 Uploading $file to release..."
gh release upload "${{ needs.prepare-release.outputs.tag }}" "$file" --clobber || echo "⚠️ Failed to upload $file"
fi
done
else
echo "⚠️ GitHub CLI not available, Android artifacts not uploaded to release"
fi
else
echo "ℹ️ No Android artifacts found to upload"
fi
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

# Step 7: Generate and upload updater JSON
# Step 6: Generate and upload updater JSON
generate-updater-json:
name: "Generate Updater JSON"
needs:
Expand Down Expand Up @@ -865,7 +837,7 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

# Step 8: Create release branch for hotfixes
# Step 7: Create release branch for hotfixes
create-release-branch:
name: "Create Release Branch"
needs:
Expand All @@ -883,15 +855,14 @@ jobs:
max_branches: 5
secrets: inherit

# Step 9: Notify about release completion
# Step 8: Notify about release completion
notify-completion:
name: "Release Complete"
runs-on: ubuntu-latest
needs:
[
pre-release-validation,
prepare-release,
build-android,
build-and-release,
generate-updater-json,
create-release-branch,
Expand All @@ -902,7 +873,6 @@ jobs:
run: |
echo "🎉 Release ${{ needs.prepare-release.outputs.tag }} completed!"
echo "✅ Desktop binaries built and published"
${{ needs.build-android.result == 'success' && 'echo "✅ Android APK/AAB built and published"' || 'echo "ℹ️ Android build skipped or failed"' }}
echo "✅ Release branch created for hotfixes"
echo "🔗 View release: https://github.com/${{ github.repository }}/releases/tag/${{ needs.prepare-release.outputs.tag }}"

Expand All @@ -915,7 +885,6 @@ jobs:
- [x] Version files synced
- [x] Git tag created: ${{ needs.prepare-release.outputs.tag }}
- [x] Desktop binaries built for all platforms
${{ needs.build-android.result == 'success' && '- [x] Android APK/AAB built and published' || '- [ ] Android build skipped or failed' }}
- [x] GitHub release created
- [x] Updater JSON generated
- [x] Release branch created for hotfixes
Expand All @@ -924,7 +893,6 @@ jobs:
- **Release Reason**: ${{ needs.check-release.outputs.release_reason }}
- **Validation**: ✅ Passed
- **Desktop Builds**: ✅ Success
- **Android Build**: ${{ needs.build-android.result == 'success' && '✅ Success' || '❌ Failed/Skipped' }}
- **Release Creation**: ✅ Success

## 🔗 Links
Expand All @@ -938,7 +906,6 @@ jobs:
- macOS Intel: [Download .dmg](https://github.com/${{ github.repository }}/releases/download/${{ needs.prepare-release.outputs.tag }}/mpesa2csv_${{ needs.prepare-release.outputs.version }}_x64.dmg)
- Linux x64: [Download .deb](https://github.com/${{ github.repository }}/releases/download/${{ needs.prepare-release.outputs.tag }}/mpesa2csv_${{ needs.prepare-release.outputs.version }}_amd64.deb)
- Linux Portable: [Download .AppImage](https://github.com/${{ github.repository }}/releases/download/${{ needs.prepare-release.outputs.tag }}/mpesa2csv_${{ needs.prepare-release.outputs.version }}_amd64.AppImage)
${{ needs.build-android.result == 'success' && format('- Android: [Download .apk](https://github.com/{0}/releases/download/{1}/mpesa2csv-v{2}-universal-release.apk)', github.repository, needs.prepare-release.outputs.tag, needs.prepare-release.outputs.version) || '' }}

---

Expand Down
25 changes: 21 additions & 4 deletions .github/workflows/pr-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ jobs:
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf curl wget unzip

- name: Get pnpm store directory
id: pnpm-cache
Expand All @@ -117,18 +117,35 @@ jobs:
path: |
~/.cargo/registry
~/.cargo/git
src-tauri/target
app/src-tauri/target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-

- name: Cache JRE for Tabula
uses: actions/cache@v4
with:
path: |
app/src-tauri/resources/build-jre
key: ${{ runner.os }}-jre-${{ hashFiles('app/src-tauri/scripts/setup-build-jre.sh') }}
restore-keys: |
${{ runner.os }}-jre-

- name: Install dependencies
if: matrix.test_type == 'frontend' || matrix.test_type == 'tauri'
if: matrix.test_type == 'frontend' || matrix.test_type == 'tauri' || matrix.test_type == 'security'
run: pnpm install --frozen-lockfile

- name: Frontend type check and build
if: matrix.test_type == 'frontend' || matrix.test_type == 'tauri'
run: pnpm run build


- name: Setup JRE for Tabula
if: matrix.test_type == 'tauri'
shell: bash
run: |
echo "🔧 Setting up JRE for Tabula PDF processing..."
bash src-tauri/scripts/setup-build-jre.sh
echo "✅ JRE setup completed"

- name: Lint check (if available)
if: matrix.test_type == 'frontend'
Expand Down
30 changes: 29 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ yarn-error.log*
pnpm-debug.log*
lerna-debug.log*


node_modules
dist
dist-ssr
Expand All @@ -23,6 +22,7 @@ dist-ssr
*.njsproj
*.sln
*.sw?

.env

# Android Build Artifacts
Expand All @@ -40,3 +40,31 @@ src-tauri/gen/android/local.properties
src-tauri/gen/android/app/build/
src-tauri/gen/android/.gradle/
src-tauri/gen/android/gradle/


# Tauri build output
src-tauri/target

# Platform-specific JRE build directory (generated at build time)
src-tauri/resources/build-jre/
src-tauri/resources/jre/

# Environment files
.env
.env.local
.env.*.local

# OS files
.DS_Store
Thumbs.db

# Temporary files
*.tmp
*.temp

# Test coverage
coverage/
*.lcov

# TypeScript cache
*.tsbuildinfo
Loading