Skip to content
Open
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
283 changes: 283 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,283 @@
name: Build and Release

on:
push:
branches:
- main
tags:
- 'v*'
pull_request:
branches:
- main

env:
CARGO_TERM_COLOR: always
S5CMD_VERSION: "2.2.2"

jobs:
test:
name: Run Tests
runs-on: ubuntu-latest
services:
minio:
image: minio/minio:latest
ports:
- 9000:9000
- 9001:9001
env:
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: minioadmin
options: --health-cmd "curl -f http://localhost:9000/minio/health/live" --health-interval 10s --health-timeout 5s --health-retries 3
steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'

- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: 8

- name: Install dependencies
run: pnpm install

- name: Download and setup s5cmd for testing
run: |
mkdir -p src-tauri/binaries
curl -L https://github.com/peak/s5cmd/releases/download/v${{ env.S5CMD_VERSION }}/s5cmd_${{ env.S5CMD_VERSION }}_Linux-64bit.tar.gz | tar xz
mv s5cmd src-tauri/binaries/s5cmd-x86_64-unknown-linux-gnu
chmod +x src-tauri/binaries/s5cmd-x86_64-unknown-linux-gnu
# Also put in PATH for test convenience
sudo cp src-tauri/binaries/s5cmd-x86_64-unknown-linux-gnu /usr/local/bin/s5cmd

- name: Create test bucket
run: |
curl -L https://dl.min.io/client/mc/release/linux-amd64/mc -o mc
chmod +x mc
./mc alias set myminio http://localhost:9000 minioadmin minioadmin
./mc mb myminio/test-bucket

- name: Install Playwright browsers
run: npx playwright install --with-deps chromium

- name: Run Playwright tests
run: pnpm test
env:
MINIO_ENDPOINT: http://localhost:9000
AWS_ACCESS_KEY_ID: minioadmin
AWS_SECRET_ACCESS_KEY: minioadmin

build-linux:
name: Build for Linux
needs: test
runs-on: ubuntu-22.04

steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'

- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: 8

- name: Install Rust stable
uses: dtolnay/rust-action@stable

- name: Install Linux dependencies
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf libssl-dev

- name: Download s5cmd for Linux
run: |
mkdir -p src-tauri/binaries
curl -L https://github.com/peak/s5cmd/releases/download/v${{ env.S5CMD_VERSION }}/s5cmd_${{ env.S5CMD_VERSION }}_Linux-64bit.tar.gz | tar xz
mv s5cmd src-tauri/binaries/s5cmd-x86_64-unknown-linux-gnu
chmod +x src-tauri/binaries/s5cmd-x86_64-unknown-linux-gnu

- name: Install frontend dependencies
run: pnpm install

- name: Build Tauri app
uses: tauri-apps/tauri-action@v0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Upload Linux artifacts
uses: actions/upload-artifact@v4
with:
name: s5cmd-gui-linux
path: |
src-tauri/target/release/bundle/deb/*.deb
src-tauri/target/release/bundle/appimage/*.AppImage
if-no-files-found: ignore

build-windows:
name: Build for Windows
needs: test
runs-on: windows-latest

steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'

- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: 8

- name: Install Rust stable
uses: dtolnay/rust-action@stable

- name: Download s5cmd for Windows
shell: powershell
run: |
New-Item -ItemType Directory -Force -Path src-tauri/binaries
Invoke-WebRequest -Uri "https://github.com/peak/s5cmd/releases/download/v${{ env.S5CMD_VERSION }}/s5cmd_${{ env.S5CMD_VERSION }}_Windows-64bit.zip" -OutFile s5cmd.zip
Expand-Archive -Path s5cmd.zip -DestinationPath .
Move-Item -Path s5cmd.exe -Destination src-tauri/binaries/s5cmd-x86_64-pc-windows-msvc.exe

- name: Install frontend dependencies
run: pnpm install

- name: Build Tauri app
uses: tauri-apps/tauri-action@v0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Upload Windows artifacts
uses: actions/upload-artifact@v4
with:
name: s5cmd-gui-windows
path: |
src-tauri/target/release/bundle/msi/*.msi
src-tauri/target/release/bundle/nsis/*.exe
if-no-files-found: ignore

build-macos:
name: Build for macOS
needs: test
runs-on: macos-latest

steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'

- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: 8

- name: Install Rust stable
uses: dtolnay/rust-action@stable

- name: Download s5cmd for macOS
run: |
mkdir -p src-tauri/binaries
# Download both Intel and ARM versions
curl -L https://github.com/peak/s5cmd/releases/download/v${{ env.S5CMD_VERSION }}/s5cmd_${{ env.S5CMD_VERSION }}_macOS-64bit.tar.gz | tar xz
mv s5cmd src-tauri/binaries/s5cmd-x86_64-apple-darwin
chmod +x src-tauri/binaries/s5cmd-x86_64-apple-darwin
# For ARM64 (M1/M2), use the ARM binary if available, otherwise use Intel with Rosetta
curl -L https://github.com/peak/s5cmd/releases/download/v${{ env.S5CMD_VERSION }}/s5cmd_${{ env.S5CMD_VERSION }}_macOS-arm64.tar.gz | tar xz || true
if [ -f s5cmd ]; then
mv s5cmd src-tauri/binaries/s5cmd-aarch64-apple-darwin
chmod +x src-tauri/binaries/s5cmd-aarch64-apple-darwin
else
# Fall back to Intel binary for ARM (will run via Rosetta)
cp src-tauri/binaries/s5cmd-x86_64-apple-darwin src-tauri/binaries/s5cmd-aarch64-apple-darwin
fi

- name: Install frontend dependencies
run: pnpm install

- name: Build Tauri app
uses: tauri-apps/tauri-action@v0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Note: For proper code signing, set these secrets:
# APPLE_CERTIFICATE: base64 encoded .p12 certificate
# APPLE_CERTIFICATE_PASSWORD: certificate password
# APPLE_SIGNING_IDENTITY: certificate name
# APPLE_ID: Apple ID email
# APPLE_PASSWORD: App-specific password
# APPLE_TEAM_ID: Team ID

- name: Upload macOS artifacts
uses: actions/upload-artifact@v4
with:
name: s5cmd-gui-macos
path: |
src-tauri/target/release/bundle/dmg/*.dmg
src-tauri/target/release/bundle/macos/*.app
if-no-files-found: ignore

release:
name: Create Release
needs: [build-linux, build-windows, build-macos]
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
permissions:
contents: write

steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts

- name: Display structure of downloaded files
run: ls -R artifacts

- name: Create Release
uses: softprops/action-gh-release@v1
with:
draft: false
prerelease: false
files: |
artifacts/**/*.deb
artifacts/**/*.AppImage
artifacts/**/*.msi
artifacts/**/*.exe
artifacts/**/*.dmg
body: |
## S5cmd GUI v${{ github.ref_name }}

A fast S3 file browser powered by s5cmd.

### Features
- s5cmd bundled - no additional installation required
- AWS SSO and Access Key authentication
- Secure credential storage in OS keychain
- Fast parallel transfers
- S3-compatible endpoint support (MinIO, etc.)

### Installation

#### Linux
- **Debian/Ubuntu**: Download the `.deb` file and install with `sudo dpkg -i s5cmd-gui_*.deb`
- **AppImage**: Download the `.AppImage` file, make it executable with `chmod +x`, and run it

#### Windows
- Download and run the `.msi` installer or the `.exe` NSIS installer

#### macOS
- Download the `.dmg` file and drag the app to your Applications folder
- **Note**: On first launch, right-click the app and select "Open" to bypass Gatekeeper
- The app is not signed. If you need a signed version, build from source with your own certificate.
43 changes: 28 additions & 15 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,31 +1,44 @@
{
"name": "s5cmd-gui",
"private": true,
"version": "0.0.0",
"version": "1.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview",
"tauri": "tauri"
"tauri": "tauri",
"test": "playwright test",
"test:ui": "playwright test --ui",
"test:headed": "playwright test --headed",
"lint": "eslint src --ext .ts,.tsx",
"format": "prettier --write \"src/**/*.{ts,tsx,css}\""
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"@tauri-apps/api": "^1.4.0",
"@aperturerobotics/chonky": "0.2.6",
"@aperturerobotics/chonky-icon-fontawesome": "0.2.2",
"path-browserify": "^1.0.1"
"@tauri-apps/api": "^1.5.0",
"@aperturerobotics/chonky": "^0.3.1",
"@aperturerobotics/chonky-icon-fontawesome": "^0.3.1",
"path-browserify": "^1.0.1",
"zustand": "^4.4.0",
"react-hot-toast": "^2.4.1",
"date-fns": "^3.0.0"
},
"devDependencies": {
"@types/react": "^18.2.15",
"@types/react-dom": "^18.2.7",
"@types/path-browserify": "^1.0.0",
"@vitejs/plugin-react": "^4.0.3",
"typescript": "^5.0.2",
"vite": "^4.4.4",

"@tauri-apps/cli": "^1.4.0",
"prettier": "3.0.0"
"@types/react": "^18.2.45",
"@types/react-dom": "^18.2.18",
"@types/path-browserify": "^1.0.2",
"@vitejs/plugin-react": "^4.2.1",
"typescript": "^5.3.3",
"vite": "^5.0.10",
"@tauri-apps/cli": "^1.5.8",
"@playwright/test": "^1.40.1",
"prettier": "^3.1.1",
"eslint": "^8.56.0",
"@typescript-eslint/eslint-plugin": "^6.15.0",
"@typescript-eslint/parser": "^6.15.0",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0"
}
}
32 changes: 32 additions & 0 deletions playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
testDir: './tests',
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: process.env.CI ? 'github' : 'html',
timeout: 60000,

use: {
baseURL: 'http://localhost:1420',
trace: 'on-first-retry',
screenshot: 'only-on-failure',
video: 'on-first-retry',
},

projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
],

webServer: {
command: 'pnpm dev',
url: 'http://localhost:1420',
reuseExistingServer: !process.env.CI,
timeout: 120000,
},
});
Loading
Loading