Skip to content

Add ru localization #53

Add ru localization

Add ru localization #53

name: Build and Release
on:
push:
branches: ["main", "develop", "feature/*"]
jobs:
build-windows:
if: github.event_name == 'push' || (github.ref_name == 'develop' || github.ref_name == 'main' || startsWith(github.ref_name, 'feature/'))
runs-on: windows-latest
outputs:
version: ${{ steps.package-version.outputs.version }}
prerelease: ${{ steps.package-version.outputs.prerelease }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "18"
cache: "npm"
- name: Install dependencies
run: npm ci
- name: Build application
run: npm run build:win
- name: Create ZIP archive from unpacked
run: |
Compress-Archive -Path "dist/win-unpacked/*" -DestinationPath "dist/DevNullifier-win-unpacked.zip"
shell: powershell
- name: Get version from package.json
id: package-version
run: |
$version = (Get-Content package.json | ConvertFrom-Json).version
$branch = "${{ github.ref_name }}"
$buildNumber = "${{ github.run_number }}"
if ($branch -eq "develop") {
$finalVersion = "v$version-dev.$buildNumber"
echo "version=$finalVersion" >> $env:GITHUB_OUTPUT
echo "prerelease=true" >> $env:GITHUB_OUTPUT
} else {
echo "version=v$version" >> $env:GITHUB_OUTPUT
echo "prerelease=false" >> $env:GITHUB_OUTPUT
}
shell: powershell
- name: Upload Windows artifacts
uses: actions/upload-artifact@v4
with:
name: windows-artifacts
path: |
dist/DevNullifier-Setup.exe
dist/DevNullifier-Setup.exe.blockmap
dist/DevNullifier-win-unpacked.zip
dist/latest.yml
build-linux:
if: github.event_name == 'push' || (github.ref_name == 'develop' || github.ref_name == 'main' || startsWith(github.ref_name, 'feature/'))
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "18"
cache: "npm"
- name: Install dependencies
run: npm ci
- name: Build application
run: npm run build:linux
- name: Create ZIP archive from unpacked
run: |
cd dist
zip -r DevNullifier-linux-unpacked.zip linux-unpacked/
- name: Find installer files
id: find-installer
run: |
APPIMAGE=$(find dist -name "*.AppImage" -type f | head -1)
DEB=$(find dist -name "*.deb" -type f | head -1)
BLOCKMAP=$(find dist -name "*.AppImage.blockmap" -type f | head -1)
echo "appimage_path=$APPIMAGE" >> $GITHUB_OUTPUT
echo "deb_path=$DEB" >> $GITHUB_OUTPUT
echo "blockmap_path=$BLOCKMAP" >> $GITHUB_OUTPUT
- name: Upload Linux artifacts
uses: actions/upload-artifact@v4
with:
name: linux-artifacts
path: |
${{ steps.find-installer.outputs.appimage_path }}
${{ steps.find-installer.outputs.blockmap_path }}
${{ steps.find-installer.outputs.deb_path }}
dist/DevNullifier-linux-unpacked.zip
dist/latest-linux.yml
build-macos:
if: github.event_name == 'push' || (github.ref_name == 'develop' || github.ref_name == 'main' || startsWith(github.ref_name, 'feature/'))
runs-on: macos-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "18"
cache: "npm"
- name: Install dependencies
run: npm ci
- name: Build application
run: npm run build:mac
- name: Create ZIP archive from unpacked
run: |
cd dist
zip -r DevNullifier-mac-unpacked.zip mac/
- name: Find installer files
id: find-installer
run: |
DMG=$(find dist -name "*.dmg" -type f | head -1)
echo "dmg_path=$DMG" >> $GITHUB_OUTPUT
- name: Upload macOS artifacts
uses: actions/upload-artifact@v4
with:
name: macos-artifacts
path: |
${{ steps.find-installer.outputs.dmg_path }}
dist/DevNullifier-mac-unpacked.zip
dist/latest-mac.yml
create-release:
if: github.event_name == 'push' && (github.ref_name == 'develop' || github.ref_name == 'main')
runs-on: ubuntu-latest
needs: [build-windows, build-linux, build-macos]
permissions:
contents: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
# Delete previous latest-dev tag and release if on develop branch
- name: Delete previous latest-dev tag and release
if: github.ref_name == 'develop'
run: |
# Delete previous release
RELEASE_ID=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
"https://api.github.com/repos/${{ github.repository }}/releases/tags/latest-dev" | \
jq -r '.id')
if [ "$RELEASE_ID" != "null" ]; then
curl -X DELETE -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
"https://api.github.com/repos/${{ github.repository }}/releases/$RELEASE_ID"
fi
# Delete previous tag
git push --delete origin latest-dev || true
continue-on-error: true
- name: Download Windows artifacts
uses: actions/download-artifact@v4
with:
name: windows-artifacts
path: artifacts/windows/
- name: Download Linux artifacts
uses: actions/download-artifact@v4
with:
name: linux-artifacts
path: artifacts/linux/
- name: Download macOS artifacts
uses: actions/download-artifact@v4
with:
name: macos-artifacts
path: artifacts/macos/
- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ needs.build-windows.outputs.version }}
release_name: ${{ github.ref_name == 'develop' && 'DevNullifier [Pre-release]' || 'DevNullifier' }} ${{ needs.build-windows.outputs.version }}
draft: false
prerelease: ${{ needs.build-windows.outputs.prerelease == 'true' }}
# Create latest-dev tag and release for develop branch
- name: Create latest-dev tag and release
if: github.ref_name == 'develop'
run: |
# Create and push latest-dev tag
git tag -f latest-dev
git push -f origin latest-dev
# Create latest-dev release
UPLOAD_URL=$(curl -X POST -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-H "Accept: application/vnd.github.v3+json" \
-d '{
"tag_name": "latest-dev",
"name": "DevNullifier [Latest Development Build]",
"draft": false,
"prerelease": true
}' \
"https://api.github.com/repos/${{ github.repository }}/releases" | \
jq -r '.upload_url' | sed 's/{.*}//')
echo "LATEST_DEV_UPLOAD_URL=$UPLOAD_URL" >> $GITHUB_ENV
# Upload assets with error handling
- name: Upload Release Assets
id: upload_assets
continue-on-error: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RELEASE_ID: ${{ steps.create_release.outputs.id }}
TAG_NAME: ${{ needs.build-windows.outputs.version }}
run: |
upload_asset() {
local file="$1"
local name="$2"
local type="$3"
local max_retries=3
local retry_count=0
while [ $retry_count -lt $max_retries ]; do
echo "Uploading $name (attempt $((retry_count + 1))/$max_retries)..."
# Check if file exists and is readable
if [ ! -f "$file" ]; then
echo "::warning::File $file not found, skipping..."
return 0
fi
# Extract base upload URL (remove {?name,label} template suffix)
local upload_url="${{ steps.create_release.outputs.upload_url }}"
upload_url="${upload_url%\{*}"
# Attempt upload with increased timeout and better error handling
response=$(curl --fail --silent --show-error \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-H "Content-Type: ${type}" \
--connect-timeout 10 \
--max-time 600 \
--retry 3 \
--retry-delay 5 \
--upload-file "${file}" \
"${upload_url}?name=${name}" 2>&1)
if [ $? -eq 0 ]; then
echo "Successfully uploaded $name"
return 0
else
echo "Failed to upload $name (attempt $((retry_count + 1))/$max_retries)"
echo "Error: $response"
retry_count=$((retry_count + 1))
if [ $retry_count -lt $max_retries ]; then
echo "Retrying in 10 seconds..."
sleep 10
fi
fi
done
echo "::error::Failed to upload $name after $max_retries attempts"
return 1
}
# Windows assets
upload_asset "artifacts/windows/DevNullifier-Setup.exe" "DevNullifier-Setup.exe" "application/octet-stream"
upload_asset "artifacts/windows/DevNullifier-Setup.exe.blockmap" "DevNullifier-Setup.exe.blockmap" "application/octet-stream"
upload_asset "artifacts/windows/latest.yml" "latest.yml" "text/yaml"
upload_asset "artifacts/windows/DevNullifier-win-unpacked.zip" "${{ github.ref_name == 'develop' && 'DevNullifier-win-unpacked-dev.zip' || 'DevNullifier-win-unpacked.zip' }}" "application/zip"
# Linux assets
APPIMAGE=$(find artifacts/linux -name "*.AppImage" -type f | head -1)
DEB=$(find artifacts/linux -name "*.deb" -type f | head -1)
BLOCKMAP=$(find artifacts/linux -name "*.AppImage.blockmap" -type f | head -1)
if [ -n "$APPIMAGE" ]; then
upload_asset "$APPIMAGE" "${{ github.ref_name == 'develop' && 'DevNullifier-linux-x64-dev.AppImage' || 'DevNullifier-linux-x64.AppImage' }}" "application/octet-stream"
fi
if [ -n "$BLOCKMAP" ]; then
upload_asset "$BLOCKMAP" "${{ github.ref_name == 'develop' && 'DevNullifier-linux-x64-dev.AppImage.blockmap' || 'DevNullifier-linux-x64.AppImage.blockmap' }}" "application/octet-stream"
fi
if [ -n "$DEB" ]; then
upload_asset "$DEB" "${{ github.ref_name == 'develop' && 'DevNullifier-linux-x64-dev.deb' || 'DevNullifier-linux-x64.deb' }}" "application/octet-stream"
fi
upload_asset "artifacts/linux/DevNullifier-linux-unpacked.zip" "${{ github.ref_name == 'develop' && 'DevNullifier-linux-unpacked-dev.zip' || 'DevNullifier-linux-unpacked.zip' }}" "application/zip"
upload_asset "artifacts/linux/latest-linux.yml" "latest-linux.yml" "text/yaml"
# macOS assets
DMG=$(find artifacts/macos -name "*.dmg" -type f | head -1)
BLOCKMAP=$(find artifacts/macos -name "*.dmg.blockmap" -type f | head -1)
if [ -n "$DMG" ]; then
upload_asset "$DMG" "${{ github.ref_name == 'develop' && 'DevNullifier-mac-x64-dev.dmg' || 'DevNullifier-mac-x64.dmg' }}" "application/octet-stream"
fi
if [ -n "$BLOCKMAP" ]; then
upload_asset "$BLOCKMAP" "${{ github.ref_name == 'develop' && 'DevNullifier-mac-x64-dev.dmg.blockmap' || 'DevNullifier-mac-x64.dmg.blockmap' }}" "application/octet-stream"
fi
upload_asset "artifacts/macos/DevNullifier-mac-unpacked.zip" "${{ github.ref_name == 'develop' && 'DevNullifier-mac-unpacked-dev.zip' || 'DevNullifier-mac-unpacked.zip' }}" "application/zip"
upload_asset "artifacts/macos/latest-mac.yml" "latest-mac.yml" "text/yaml"
# Cleanup on failure
- name: Cleanup on failure
if: steps.upload_assets.outcome == 'failure'
run: |
echo "Upload failed, cleaning up..."
# Delete the release
curl -X DELETE \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
"https://api.github.com/repos/${{ github.repository }}/releases/${{ steps.create_release.outputs.id }}"
# Delete the tag
git push --delete origin ${{ needs.build-windows.outputs.version }} || true
# If on develop, also clean up latest-dev
if [ "${{ github.ref_name }}" = "develop" ]; then
# Delete latest-dev release
LATEST_DEV_ID=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
"https://api.github.com/repos/${{ github.repository }}/releases/tags/latest-dev" | \
jq -r '.id')
if [ "$LATEST_DEV_ID" != "null" ]; then
curl -X DELETE -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
"https://api.github.com/repos/${{ github.repository }}/releases/$LATEST_DEV_ID"
fi
# Delete latest-dev tag
git push --delete origin latest-dev || true
fi
exit 1
# Upload to latest-dev release if on develop branch and main upload succeeded
- name: Upload assets to latest-dev release
if: github.ref_name == 'develop' && steps.upload_assets.outcome == 'success'
run: |
# Function to upload asset
upload_asset() {
local file="$1"
local name="$2"
local type="$3"
local max_retries=3
local retry_count=0
while [ $retry_count -lt $max_retries ]; do
echo "Uploading $name to latest-dev (attempt $((retry_count + 1))/$max_retries)..."
# Check if file exists and is readable
if [ ! -f "$file" ]; then
echo "::warning::File $file not found, skipping..."
return 0
fi
# Extract base upload URL (remove {?name,label} template suffix)
local upload_url="${LATEST_DEV_UPLOAD_URL}"
upload_url="${upload_url%\{*}"
# Attempt upload with increased timeout and better error handling
response=$(curl --fail --silent --show-error \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-H "Content-Type: ${type}" \
--connect-timeout 10 \
--max-time 600 \
--retry 3 \
--retry-delay 5 \
--upload-file "${file}" \
"${upload_url}?name=${name}" 2>&1)
if [ $? -eq 0 ]; then
echo "Successfully uploaded $name to latest-dev"
return 0
else
echo "Failed to upload $name to latest-dev (attempt $((retry_count + 1))/$max_retries)"
echo "Error: $response"
retry_count=$((retry_count + 1))
if [ $retry_count -lt $max_retries ]; then
echo "Retrying in 10 seconds..."
sleep 10
fi
fi
done
echo "::error::Failed to upload $name to latest-dev after $max_retries attempts"
return 1
}
# Windows assets
upload_asset "artifacts/windows/DevNullifier-Setup.exe" "DevNullifier-Setup.exe" "application/octet-stream"
upload_asset "artifacts/windows/DevNullifier-Setup.exe.blockmap" "DevNullifier-Setup.exe.blockmap" "application/octet-stream"
upload_asset "artifacts/windows/latest.yml" "latest.yml" "text/yaml"
upload_asset "artifacts/windows/DevNullifier-win-unpacked.zip" "DevNullifier-win-unpacked.zip" "application/zip"
# Linux assets
APPIMAGE=$(find artifacts/linux -name "*.AppImage" -type f | head -1)
DEB=$(find artifacts/linux -name "*.deb" -type f | head -1)
BLOCKMAP=$(find artifacts/linux -name "*.AppImage.blockmap" -type f | head -1)
if [ -n "$APPIMAGE" ]; then
upload_asset "$APPIMAGE" "DevNullifier-linux-x64.AppImage" "application/octet-stream"
fi
if [ -n "$BLOCKMAP" ]; then
upload_asset "$BLOCKMAP" "DevNullifier-linux-x64.AppImage.blockmap" "application/octet-stream"
fi
if [ -n "$DEB" ]; then
upload_asset "$DEB" "DevNullifier-linux-x64.deb" "application/octet-stream"
fi
upload_asset "artifacts/linux/DevNullifier-linux-unpacked.zip" "DevNullifier-linux-unpacked.zip" "application/zip"
upload_asset "artifacts/linux/latest-linux.yml" "latest-linux.yml" "text/yaml"
# macOS assets
DMG=$(find artifacts/macos -name "*.dmg" -type f | head -1)
BLOCKMAP=$(find artifacts/macos -name "*.dmg.blockmap" -type f | head -1)
if [ -n "$DMG" ]; then
upload_asset "$DMG" "DevNullifier-mac-x64.dmg" "application/octet-stream"
fi
if [ -n "$BLOCKMAP" ]; then
upload_asset "$BLOCKMAP" "DevNullifier-mac-x64.dmg.blockmap" "application/octet-stream"
fi
upload_asset "artifacts/macos/DevNullifier-mac-unpacked.zip" "DevNullifier-mac-unpacked.zip" "application/zip"
upload_asset "artifacts/macos/latest-mac.yml" "latest-mac.yml" "text/yaml"