Skip to content

Merge pull request #175 from alvarorichard/dev #1335

Merge pull request #175 from alvarorichard/dev

Merge pull request #175 from alvarorichard/dev #1335

Workflow file for this run

name: GoAnime CI
on:
push:
branches: [ main, dev]
pull_request:
branches: [ main, dev ]
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ ubuntu-latest, windows-latest, macos-latest ]
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.26.2'
- name: Install dependencies (Linux)
if: runner.os == 'Linux'
run: |
sudo apt update
sudo apt install -y mpv
- name: Install dependencies (Windows)
if: runner.os == 'Windows'
shell: pwsh
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
$headers = @{ "User-Agent" = "GoAnime-CI" }
if ($env:GITHUB_TOKEN) { $headers["Authorization"] = "Bearer $env:GITHUB_TOKEN" }
$release = Invoke-RestMethod -Uri "https://api.github.com/repos/zhongfly/mpv-winbuild/releases/latest" -Headers $headers
$asset = $release.assets | Where-Object { $_.name -like "mpv-x86_64-v3-*.7z" } | Select-Object -First 1
if (-not $asset) { $asset = $release.assets | Where-Object { $_.name -like "mpv-x86_64-*.7z" } | Select-Object -First 1 }
Write-Host "Downloading $($asset.name)..."
Invoke-WebRequest -Uri $asset.browser_download_url -OutFile mpv.7z -Headers @{ "Accept"="application/octet-stream"; "User-Agent"="GoAnime-CI" }
7z x mpv.7z -ompv_tmp -y
$mpvExe = Get-ChildItem -Path mpv_tmp -Recurse -Filter "mpv.exe" | Select-Object -First 1
$mpvDir = $mpvExe.DirectoryName
echo "$mpvDir" | Out-File -Append -Encoding utf8 $env:GITHUB_PATH
Write-Host "mpv added to PATH from $mpvDir"
& $mpvExe.FullName --version
- name: Install dependencies (macOS)
if: runner.os == 'macOS'
run: |
brew install mpv
- name: Run macOS Socket Tests (macOS only)
if: runner.os == 'macOS'
run: |
echo "=== Testing macOS-specific socket path handling ==="
echo "TMPDIR=$TMPDIR"
go test -race -v ./internal/player/test/... -run "Socket|MacOS" -count=1
- name: Get dependencies
run: go mod download
- name: Run golangci-lint
uses: golangci/golangci-lint-action@v7
with:
version: v2.11.4
args: --timeout=15m
- name: Install Gosec
run: go install github.com/securego/gosec/v2/cmd/gosec@latest
- name: Run Gosec Security Scanner
run: gosec ./...
- name: Install govulncheck
run: go install golang.org/x/vuln/cmd/govulncheck@latest
- name: Scan for vulnerabilities
run: govulncheck ./...
- name: Run tests
shell: bash
run: go test -race -v -coverprofile=coverage.out ./...
- name: Run source health diagnostics
if: runner.os == 'Linux'
shell: bash
run: go test -tags sourcehealth -run TestSourceHealthLive -count=1 -v ./internal/scraper
build-binaries:
needs: test
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- os: ubuntu-latest
goos: linux
goarch: amd64
binary_name: goanime-linux
asset_name: goanime-linux-amd64
- os: windows-latest
goos: windows
goarch: amd64
binary_name: goanime.exe
asset_name: goanime-windows-amd64
- os: macos-latest
goos: darwin
goarch: amd64
binary_name: goanime-darwin-amd64
asset_name: goanime-darwin-amd64
- os: macos-latest
goos: darwin
goarch: arm64
binary_name: goanime-darwin-arm64
asset_name: goanime-darwin-arm64
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.26.2'
- name: Get dependencies
run: go mod download
- name: Build binary
shell: bash
env:
CGO_ENABLED: 0
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
run: |
mkdir -p dist
go build -o dist/${{ matrix.binary_name }} -ldflags="-s -w" -trimpath ./cmd/goanime
- name: Create archive (Unix)
if: matrix.goos != 'windows'
shell: bash
run: |
cd dist
tar -czvf ${{ matrix.asset_name }}.tar.gz ${{ matrix.binary_name }}
if command -v sha256sum >/dev/null 2>&1; then
sha256sum ${{ matrix.asset_name }}.tar.gz > ${{ matrix.asset_name }}.tar.gz.sha256
elif command -v shasum >/dev/null 2>&1; then
shasum -a 256 ${{ matrix.asset_name }}.tar.gz > ${{ matrix.asset_name }}.tar.gz.sha256
fi
- name: Create archive (Windows)
if: matrix.goos == 'windows'
shell: pwsh
run: |
cd dist
Compress-Archive -Path ${{ matrix.binary_name }} -DestinationPath ${{ matrix.asset_name }}.zip
(Get-FileHash -Algorithm SHA256 ${{ matrix.asset_name }}.zip).Hash.ToLower() + " ${{ matrix.asset_name }}.zip" | Out-File -Encoding utf8 ${{ matrix.asset_name }}.zip.sha256
- name: Upload binary artifact (Unix)
if: matrix.goos != 'windows'
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.asset_name }}
path: |
dist/${{ matrix.asset_name }}.tar.gz
dist/${{ matrix.asset_name }}.tar.gz.sha256
retention-days: 30
- name: Upload binary artifact (Windows)
if: matrix.goos == 'windows'
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.asset_name }}
path: |
dist/${{ matrix.asset_name }}.zip
dist/${{ matrix.asset_name }}.zip.sha256
retention-days: 30
# Windows Installer Job - Creates an offline installer with bundled mpv
build-windows-installer:
needs: test
runs-on: windows-latest
steps:
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.26.2'
- name: Check out code
uses: actions/checkout@v4
- name: Get dependencies
run: go mod download
- name: Install GCC for CGO (SQLite support)
shell: pwsh
run: |
# Check if mingw/gcc is already available on the runner
$gccPaths = @("C:\ProgramData\mingw64\mingw64\bin", "C:\mingw64\bin", "C:\msys64\mingw64\bin")
$found = $false
foreach ($p in $gccPaths) {
if (Test-Path "$p\gcc.exe") {
echo $p | Out-File -Append -Encoding utf8 $env:GITHUB_PATH
$env:PATH = "$p;$env:PATH"
$found = $true
Write-Host "Found existing GCC at $p"
break
}
}
if (-not $found) {
Write-Host "Installing MinGW via Chocolatey..."
for ($i = 1; $i -le 3; $i++) {
choco install mingw -y --no-progress && break
Write-Host "Retry $i/3..."; Start-Sleep -Seconds 10
}
$env:PATH = "C:\ProgramData\mingw64\mingw64\bin;$env:PATH"
}
gcc --version
Write-Host "GCC available for CGO builds"
- name: Build GoAnime binary with SQLite
shell: pwsh
env:
CGO_ENABLED: 1
GOOS: windows
GOARCH: amd64
CC: gcc
run: |
# Add MinGW to PATH
$env:PATH = "C:\ProgramData\mingw64\mingw64\bin;$env:PATH"
# Create staging directory structure
New-Item -ItemType Directory -Force -Path "build/staging/bin"
# Build the Go application with CGO enabled for SQLite support
go build -o build/staging/goanime.exe -ldflags="-s -w" -trimpath -tags="windows" ./cmd/goanime
Write-Host "GoAnime binary built successfully with SQLite support"
Get-ChildItem build/staging/
- name: Download mpv for Windows
shell: pwsh
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Download latest mpv from zhongfly/mpv-winbuild GitHub releases
# Using GitHub API to get the latest release and download x86_64-v3 build
Write-Host "Fetching latest mpv release from zhongfly/mpv-winbuild..."
# Get the latest release info from GitHub API (authenticated to avoid rate limits)
$headers = @{ "User-Agent" = "GoAnime-CI" }
if ($env:GITHUB_TOKEN) {
$headers["Authorization"] = "Bearer $env:GITHUB_TOKEN"
}
$releaseInfo = Invoke-RestMethod -Uri "https://api.github.com/repos/zhongfly/mpv-winbuild/releases/latest" -Headers $headers
Write-Host "Latest release: $($releaseInfo.tag_name)"
# Find the x86_64-v3 asset (optimized for modern CPUs)
$mpvAsset = $releaseInfo.assets | Where-Object { $_.name -like "mpv-x86_64-v3-*.7z" } | Select-Object -First 1
if (-not $mpvAsset) {
# Fallback to regular x86_64 if v3 not found
$mpvAsset = $releaseInfo.assets | Where-Object { $_.name -like "mpv-x86_64-*.7z" -and $_.name -notlike "*v3*" } | Select-Object -First 1
}
if (-not $mpvAsset) {
Write-Error "No suitable mpv asset found in release"
exit 1
}
$mpvUrl = $mpvAsset.browser_download_url
$mpvArchive = "mpv.7z"
Write-Host "Downloading: $($mpvAsset.name)"
Write-Host "URL: $mpvUrl"
# Download mpv archive from GitHub releases with proper headers
Invoke-WebRequest -Uri $mpvUrl -OutFile $mpvArchive -Headers @{ "Accept" = "application/octet-stream"; "User-Agent" = "GoAnime-CI" }
# Verify download
if (-not (Test-Path $mpvArchive) -or (Get-Item $mpvArchive).Length -lt 1000000) {
Write-Error "Download failed or file too small"
exit 1
}
Write-Host "Downloaded mpv archive ($(((Get-Item $mpvArchive).Length / 1MB).ToString('F2')) MB), extracting..."
# Extract using 7z (available on Windows runners)
7z x $mpvArchive -ompv_extracted -y
# Find and copy mpv.exe and required DLLs to staging
$mpvExe = Get-ChildItem -Path "mpv_extracted" -Recurse -Filter "mpv.exe" | Select-Object -First 1
if ($mpvExe) {
$mpvDir = $mpvExe.DirectoryName
# Copy mpv.exe
Copy-Item $mpvExe.FullName -Destination "build/staging/bin/mpv.exe"
Write-Host "mpv.exe copied to build/staging/bin/"
# Copy all required DLLs from the same directory
$dlls = Get-ChildItem -Path $mpvDir -Filter "*.dll" -ErrorAction SilentlyContinue
if ($dlls) {
foreach ($dll in $dlls) {
Copy-Item $dll.FullName -Destination "build/staging/bin/" -Force
Write-Host "Copied DLL: $($dll.Name)"
}
}
# Verify mpv version
& "build/staging/bin/mpv.exe" --version
} else {
Write-Error "mpv.exe not found in extracted archive"
exit 1
}
# Cleanup extracted files
Remove-Item -Path "mpv_extracted" -Recurse -Force -ErrorAction SilentlyContinue
Remove-Item -Path $mpvArchive -Force -ErrorAction SilentlyContinue
# Verify files exist
Write-Host "Staging directory contents:"
Get-ChildItem -Recurse build/staging/
- name: Install Inno Setup
shell: pwsh
run: |
# Check if Inno Setup is already installed
$iscc = "C:\Program Files (x86)\Inno Setup 6\ISCC.exe"
if (Test-Path $iscc) {
Write-Host "Inno Setup already installed at: $iscc"
} else {
Write-Host "Installing Inno Setup via Chocolatey..."
for ($i = 1; $i -le 3; $i++) {
choco install innosetup -y --no-progress && break
Write-Host "Retry $i/3..."; Start-Sleep -Seconds 10
}
if (-not (Test-Path $iscc)) {
Write-Error "Inno Setup installation failed - ISCC.exe not found"
exit 1
}
Write-Host "Inno Setup installed successfully"
}
- name: Create dist directory
shell: pwsh
run: |
New-Item -ItemType Directory -Force -Path "dist"
- name: Build Windows Installer
shell: pwsh
run: |
# Add Inno Setup to PATH
$env:PATH = "C:\Program Files (x86)\Inno Setup 6;$env:PATH"
# Verify ISCC exists
$iscc = "C:\Program Files (x86)\Inno Setup 6\ISCC.exe"
if (-not (Test-Path $iscc)) {
Write-Error "Inno Setup compiler not found at $iscc"
exit 1
}
Write-Host "Building installer with Inno Setup..."
& $iscc "build/install.iss"
if ($LASTEXITCODE -ne 0) {
Write-Error "Inno Setup compilation failed"
exit 1
}
Write-Host "Installer built successfully"
Get-ChildItem dist/
- name: Generate installer checksum
shell: pwsh
run: |
$installer = Get-ChildItem -Path "dist" -Filter "*.exe" | Select-Object -First 1
if ($installer) {
$hash = (Get-FileHash -Algorithm SHA256 $installer.FullName).Hash.ToLower()
"$hash $($installer.Name)" | Out-File -Encoding utf8 "dist/$($installer.BaseName).sha256"
Write-Host "Checksum generated: $hash"
}
- name: Upload Windows Installer artifact
uses: actions/upload-artifact@v4
with:
name: goanime-windows-installer
path: |
dist/GoAnime-Installer-*.exe
dist/GoAnime-Installer-*.sha256
retention-days: 30