Created
May 26, 2025 15:50
-
-
Save vasmarfas/8fa0db21027cccb5396bee9a8424c8b6 to your computer and use it in GitHub Desktop.
Gitlab CI for selfhosted Gitlab instance and workers (macOS + Windows) on example DotaDiviner app
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
stages: | |
- build | |
- upload | |
- create_release | |
- update_files | |
variables: | |
ANDROID_HOME: "C:/Users/*user*/AppData/Local/Android/Sdk" | |
JAVA_HOME: "C:/Program Files/Java/jdk-21" | |
before_script: | |
- echo "Setting up environment variables" | |
# - export PATH=$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools:$PATH | |
# - export PATH=$JAVA_HOME/bin:$PATH | |
- echo "Terminating Java processes" | |
- taskkill /F /IM java.exe /T 2>$null; if ($LASTEXITCODE -eq 0) { echo 'Java.exe terminated' } else { echo 'No Java.exe processes found' } | |
#- echo "Cleaning up old build files" | |
#- Remove-Item -Path "composeApp/build" -Recurse -Force -ErrorAction SilentlyContinue | |
- echo "Reading version from file" | |
- $VERSION = Get-Content -Path "mainProjectVersion.txt" | |
- echo "Version $VERSION" | |
build_apk: | |
stage: build | |
tags: | |
- winserver | |
before_script: | |
- echo "Terminating Java processes" | |
- taskkill /F /IM java.exe /T 2>$null; if ($LASTEXITCODE -eq 0) { echo 'Java.exe terminated' } else { echo 'No Java.exe processes found' } | |
- echo "Reading version from file" | |
- $VERSION = Get-Content -Path "mainProjectVersion.txt" | |
- echo "Version $VERSION" | |
#- echo "Cleaning up old build files" | |
#- Remove-Item -Path "composeApp/build" -Recurse -Force -ErrorAction SilentlyContinue | |
script: | |
- echo "Terminating Java processes" | |
- taskkill /F /IM java.exe /T 2>$null; if ($LASTEXITCODE -eq 0) { echo 'Java.exe terminated' } else { echo 'No Java.exe processes found' } | |
#- echo "Cleaning up old build files" | |
#- Remove-Item -Path "composeApp/build" -Recurse -Force -ErrorAction SilentlyContinue | |
- echo "Building APK" | |
- ./gradlew assembleRelease | |
# - $VERSION = Get-Content -Path "mainProjectVersion.txt" | |
- echo "Version $VERSION" | |
- cp -Force ./composeApp/build/outputs/apk/release/composeApp-release.apk ../outFile/DotaDiviner-$VERSION.apk # Переименование APK | |
- echo "Terminating Java processes" | |
- taskkill /F /IM java.exe /T 2>$null; if ($LASTEXITCODE -eq 0) { echo 'Java.exe terminated' } else { echo 'No Java.exe processes found' } | |
artifacts: | |
paths: | |
- "outFiles/DotaDiviner-$VERSION.apk" # Указываем новое имя, и оно будет корректно подставлено | |
- outFiles/DotaDiviner-$VERSION.apk # Указываем новое имя, и оно будет корректно подставлено | |
only: | |
- master | |
build_aab: | |
stage: build | |
tags: | |
- winserver | |
before_script: | |
- echo "Terminating Java processes" | |
- taskkill /F /IM java.exe /T 2>$null; if ($LASTEXITCODE -eq 0) { echo 'Java.exe terminated' } else { echo 'No Java.exe processes found' } | |
#- echo "Cleaning up old build files" | |
#- Remove-Item -Path "composeApp/build" -Recurse -Force -ErrorAction SilentlyContinue | |
script: | |
- echo "Building AAB" | |
- ./gradlew bundleRelease | |
- $VERSION = Get-Content -Path "mainProjectVersion.txt" | |
- echo "Version $VERSION" | |
- cp -Force ./composeApp/build/outputs/bundle/release/composeApp-release.aab ../outFile/DotaDiviner-$VERSION.aab # Переименование AAB | |
- echo "Terminating Java processes" | |
- taskkill /F /IM java.exe /T 2>$null; if ($LASTEXITCODE -eq 0) { echo 'Java.exe terminated' } else { echo 'No Java.exe processes found' } | |
artifacts: | |
paths: | |
- outFiles/DotaDiviner-$VERSION.aab # Указываем новое имя | |
only: | |
- master | |
build_msi: | |
stage: build | |
tags: | |
- winserver | |
variables: | |
GRADLE_USER_HOME: "C:/Users/*user*/.gradle" | |
before_script: | |
- echo "Terminating Java processes" | |
- taskkill /F /IM java.exe /T 2>$null; if ($LASTEXITCODE -eq 0) { echo 'Java.exe terminated' } else { echo 'No Java.exe processes found' } | |
#- echo "Cleaning up old build files" | |
#- Remove-Item -Path "composeApp/build" -Recurse -Force -ErrorAction SilentlyContinue | |
script: | |
- echo "Building MSI using batch file" | |
- ./gradlew clean | |
- echo "Forcing Wix download" | |
- ./gradlew downloadWix --rerun-tasks | |
- echo "Checking if Wix is properly downloaded" | |
- if (Test-Path "C:\Users\*user*\.gradle\compose-jb\wix311.zip") { echo "Wix ZIP exists" } else { echo "Wix ZIP missing"; exit 1 } | |
- ./gradlew packageMsi | |
- echo "Searching for MSI file" | |
- $MSI_FILE = Get-ChildItem -Path "composeApp/build/compose/binaries/main/msi" -Filter "DotaDiviner*.msi" | Select-Object -First 1 | |
- echo "Found MSI file $MSI_FILE" | |
- msiSigning/signtool.exe sign /fd SHA256 /f msiSigning/cert.pfx /p "password" /t http://timestamp.digicert.com "$MSI_FILE" | |
- $VERSION = Get-Content -Path "mainProjectVersion.txt" | |
- echo "Signing completed for $MSI_FILE" | |
# Перемещаем подписанный файл в нужную директорию для артефактов | |
- cp -Force $MSI_FILE ../outFile/DotaDiviner-$VERSION.msi | |
- echo "Terminating Java processes" | |
- taskkill /F /IM java.exe /T 2>$null; if ($LASTEXITCODE -eq 0) { echo 'Java.exe terminated' } else { echo 'No Java.exe processes found' } | |
artifacts: | |
paths: | |
- outFiles/DotaDiviner-$VERSION.msi | |
only: | |
- master | |
# iOS и macOS задачи | |
build_ios: | |
stage: build | |
tags: | |
- macos-mini | |
variables: | |
JAVA_HOME: "$HOME/jdk/Home" | |
before_script: | |
- echo "Настройка CI окружения для iOS сборки" | |
# Разблокировка основной связки DotaDivinerCI.keychain | |
- security unlock-keychain -p "keychain-password" DotaDivinerCI.keychain | |
- security set-keychain-settings -t 7200 -l DotaDivinerCI.keychain | |
# Разблокировка всех системных связок ключей | |
- security unlock-keychain -p "keychain-password" "$HOME/Library/Keychains/login.keychain-db" | |
- security unlock-keychain -p "keychain-password" "$HOME/Library/Keychains/login.keychain-db" | |
- security set-keychain-settings -t 7200 -l "$HOME/Library/Keychains/login.keychain-db" | |
# Если у вас есть TemporDotaDivinerKeychain, разблокируем её тоже | |
- | | |
if [ -f "$HOME/Library/Keychains/TemporDotaDivinerKeychain.keychain-db" ]; then | |
security unlock-keychain -p "keychain-password" "$HOME/Library/Keychains/TemporDotaDivinerKeychain.keychain-db" | |
security set-keychain-settings -t 7200 -l "$HOME/Library/Keychains/TemporDotaDivinerKeychain.keychain-db" | |
fi | |
# Устанавливаем порядок поиска в связках ключей (DotaDivinerCI первым) | |
- security list-keychains -d user -s DotaDivinerCI.keychain "$HOME/Library/Keychains/login.keychain-db" "/Library/Keychains/System.keychain" | |
# Настройка разделов для всех связок | |
- 'security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "keychain-password" DotaDivinerCI.keychain' | |
- 'security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "keychain-password" "$HOME/Library/Keychains/TemporDotaDivinerKeychain.keychain-db"' | |
# Отображение доступных сертификатов | |
- security find-identity -v -p codesigning | |
# Проверяем доступность xcodebuild | |
- xcrun xcodebuild -version | |
script: | | |
cd iosApp | |
xcodebuild -project iosApp.xcodeproj \ | |
-scheme iosApp \ | |
-sdk iphoneos \ | |
-configuration Release \ | |
-archivePath ../outIos/iosApp.xcarchive \ | |
archive \ | |
CODE_SIGNING_REQUIRED=YES \ | |
CODE_SIGNING_ALLOWED=YES | |
cd .. | |
xcodebuild -exportArchive \ | |
-archivePath outIos/iosApp.xcarchive \ | |
-exportPath outIos/ipa \ | |
-exportOptionsPlist ExportOptions.plist | |
artifacts: | |
paths: | |
- "outIos/ipa/Dota Diviner.ipa" | |
only: | |
- master | |
build_macos: | |
stage: build | |
tags: | |
- macos-mini | |
variables: | |
JAVA_HOME: "$HOME/jdk/Home" | |
before_script: | |
- echo "Настройка CI окружения для macOS сборки" | |
- security unlock-keychain -p "keychain-password" DotaDivinerCI.keychain | |
- security set-keychain-settings -t 7200 -l DotaDivinerCI.keychain | |
- security list-keychains -d user -s DotaDivinerCI.keychain "$HOME/Library/Keychains/login.keychain-db" "/Library/Keychains/System.keychain" | |
- 'security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "keychain-password" DotaDivinerCI.keychain' | |
# Отображение доступных сертификатов | |
- security find-identity -v -p codesigning | |
# Проверяем JAVA_HOME | |
- export JAVA_HOME="$HOME/jdk/Home" | |
- echo "JAVA_HOME=$JAVA_HOME" | |
# Проверяем доступность xcodebuild | |
- xcrun xcodebuild -version | |
script: | | |
echo "Building macOS app" | |
cd $CI_PROJECT_DIR | |
export VERSION=$(cat mainProjectVersion.txt) | |
echo "Building macOS app version $VERSION" | |
# Для решения проблемы с версией (3.02.23 vs 3.2.23) | |
# Выводим информацию о текущей версии | |
echo "Текущий формат версии: $VERSION" | |
# Аналогично ci_pre_xcodebuild.sh в Xcode Cloud | |
./gradlew commonizeNativeDistribution | |
./gradlew :composeApp:packageReleasePkg -PmacOsAppStoreRelease=true | |
echo "macOS app build completed" | |
# Проверяем создались ли файлы | |
echo "Checking for created .pkg files:" | |
find composeApp/build -name "*.pkg" -type f || echo "No .pkg files found" | |
# Проверяем конкретную директорию | |
if [ -d "composeApp/build/compose/binaries/main/pkg" ]; then | |
echo "Directory composeApp/build/compose/binaries/main/pkg exists:" | |
ls -la composeApp/build/compose/binaries/main/pkg/ | |
else | |
echo "Directory composeApp/build/compose/binaries/main/pkg does not exist" | |
echo "Available build directories:" | |
find composeApp/build -type d -name "*pkg*" || echo "No pkg directories found" | |
fi | |
artifacts: | |
paths: | |
- composeApp/build/compose/binaries/main-release/pkg/DotaDiviner-*.pkg | |
only: | |
- master | |
# build_wasmjs: | |
# stage: build | |
# tags: | |
# - winserver | |
# before_script: | |
# - echo "Terminating Java processes" | |
# - taskkill /F /IM java.exe /T 2>$null; if ($LASTEXITCODE -eq 0) { echo 'Java.exe terminated' } else { echo 'No Java.exe processes found' } | |
# #- echo "Cleaning up old build files" | |
# #- Remove-Item -Path "composeApp/build" -Recurse -Force -ErrorAction SilentlyContinue | |
# script: | |
# - echo "Building WASM" | |
# - ./gradlew kotlinUpgradeYarnLock | |
# - ./gradlew wasmJsBrowserDistribution | |
# - $VERSION = Get-Content -Path "mainProjectVersion.txt" | |
# - echo "Version $VERSION" | |
# - echo "Zipping productionExecutable" | |
# - powershell -Command "Compress-Archive -Path './composeApp/build/dist/wasmJs/productionExecutable/' -DestinationPath './outFiles/productionExecutable-$VERSION.zip'" | |
# - cp -Force ./outFiles/productionExecutable-$VERSION.zip ../outFile/DotaDiviner-$VERSION.zip | |
# - echo "Terminating Java processes" | |
# - taskkill /F /IM java.exe /T 2>$null; if ($LASTEXITCODE -eq 0) { echo 'Java.exe terminated' } else { echo 'No Java.exe processes found' } | |
# artifacts: | |
# paths: | |
# - outFiles/productionExecutable-$VERSION.zip | |
# only: | |
# - master | |
build_wasmjs_on_mac: | |
stage: build | |
tags: | |
- macos-mini | |
before_script: | |
- echo "Setting correct JAVA_HOME for macOS" | |
- export JAVA_HOME=$(/usr/libexec/java_home) | |
- java -version | |
script: | |
- echo "Building WASM" | |
- ./gradlew kotlinUpgradeYarnLock | |
- ./gradlew wasmJsBrowserDistribution | |
- VERSION=$(cat mainProjectVersion.txt) | |
- echo "Version $VERSION" | |
- echo "Zipping productionExecutable" | |
- mkdir -p outFiles | |
- mkdir -p ../outFile | |
- zip -r "./outFiles/productionExecutable-$VERSION.zip" ./composeApp/build/dist/wasmJs/productionExecutable/ | |
- cp -f "./outFiles/productionExecutable-$VERSION.zip" "../outFile/DotaDiviner-$VERSION.zip" | |
artifacts: | |
paths: | |
- outFiles/productionExecutable-$VERSION.zip | |
only: | |
- master | |
#build_js: | |
# stage: build | |
# tags: | |
# - winserver | |
# before_script: | |
# - echo "Terminating Java processes" | |
# - taskkill /F /IM java.exe /T 2>$null; if ($LASTEXITCODE -eq 0) { echo 'Java.exe terminated' } else { echo 'No Java.exe processes found' } | |
# #- echo "Cleaning up old build files" | |
# #- Remove-Item -Path "composeApp/build" -Recurse -Force -ErrorAction SilentlyContinue | |
# script: | |
# - echo "Building JS" | |
# - ./gradlew kotlinUpgradeYarnLock | |
# - ./gradlew jsBrowserDistribution | |
# - $VERSION = Get-Content -Path "mainProjectVersion.txt" | |
# - echo "Version $VERSION" | |
# - echo "Zipping productionExecutable" | |
# - powershell -Command "Compress-Archive -Path './composeApp/build/dist/js/productionExecutable/' -DestinationPath './outFiles/productionExecutableJs-$VERSION.zip'" | |
# - cp -Force ./outFiles/productionExecutableJs-$VERSION.zip ../outFile/DotaDivinerJs-$VERSION.zip | |
# - echo "Terminating Java processes" | |
# - taskkill /F /IM java.exe /T 2>$null; if ($LASTEXITCODE -eq 0) { echo 'Java.exe terminated' } else { echo 'No Java.exe processes found' } | |
# | |
# artifacts: | |
# paths: | |
# - outFiles/productionExecutable-$VERSION.zip | |
# only: | |
# - master | |
build_js_on_mac: | |
stage: build | |
tags: | |
- macos-mini | |
before_script: | |
- echo "Setting correct JAVA_HOME for macOS" | |
- export JAVA_HOME=$(/usr/libexec/java_home) | |
- java -version | |
script: | |
- echo "Building JS" | |
- ./gradlew kotlinUpgradeYarnLock | |
- ./gradlew jsBrowserDistribution | |
- VERSION=$(cat mainProjectVersion.txt) | |
- echo "Version $VERSION" | |
- echo "Zipping productionExecutable" | |
- mkdir -p outFiles | |
- mkdir -p ../outFile | |
- zip -r "./outFiles/productionExecutableJs-$VERSION.zip" ./composeApp/build/dist/js/productionExecutable/ | |
- cp -f "./outFiles/productionExecutableJs-$VERSION.zip" "../outFile/DotaDivinerJs-$VERSION.zip" | |
artifacts: | |
paths: | |
- outFiles/productionExecutableJs-$VERSION.zip | |
only: | |
- master | |
upload_apk: | |
stage: upload | |
tags: | |
- winserver | |
script: | |
- echo "Uploading APK file..." | |
- echo "Current Directory $(Get-Location)" | |
- $VERSION = Get-Content -Path "mainProjectVersion.txt" | |
- if (-not $VERSION) { | |
Write-Error "Version not found in mainProjectVersion.txt" | |
exit 1 | |
} | |
- $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]" | |
- $headers.Add("x-api-key", "apikey") | |
- $headers.Add("Albumuuid", "uuid") | |
- $APK_FILE = "../outFile/DotaDiviner-$VERSION.apk" | |
- echo "APK_FILE is $APK_FILE" | |
- if (!(Test-Path $APK_FILE)) { Write-Error "APK file not found $APK_FILE"; exit 1 } | |
- $multipartContent = [System.Net.Http.MultipartFormDataContent]::new() | |
- echo "Current Directory $(Get-Location)" | |
- $fullPathApk = (Get-Item "../outFile/DotaDiviner-$VERSION.apk").FullName | |
- echo "Full path $fullPathApk" | |
- | | |
if (!(Test-Path $fullPathApk)) { | |
Write-Error "File not found: $fullPathApk" | |
exit 1 | |
} | |
- $FileStream = [System.IO.FileStream]::new($fullPathApk, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read) | |
- $fileContent = [System.Net.Http.StreamContent]::new($FileStream) | |
- $fileHeader = [System.Net.Http.Headers.ContentDispositionHeaderValue]::new("form-data") | |
- $fileHeader.Name = "file" | |
- $fileHeader.FileName = (Split-Path $fullPathApk -Leaf) | |
- $fileContent.Headers.ContentDisposition = $fileHeader | |
- $multipartContent.Add($fileContent) | |
- | | |
try { | |
$response = Invoke-RestMethod 'https://chibisafe' -Method 'POST' -Headers $headers -Body $multipartContent | |
echo "Response from API: $($response | ConvertTo-Json -Depth 10)" | |
if ($response -and $response.url) { | |
$UPLOAD_URL_APK = $response.url | |
echo "UPLOAD_URL_APK=$UPLOAD_URL_APK" | |
# Записываем в переменную окружения GitLab | |
echo "UPLOAD_URL_APK=$UPLOAD_URL_APK" | Out-File -FilePath "$CI_PIPELINE_ID.env" -Append | |
Write-Output "Upload successful: $UPLOAD_URL_APK" | |
echo "UPLOAD_URL_APK=$UPLOAD_URL_APK" | Out-File -FilePath "upload_apk.env" | |
} else { | |
Write-Error "Upload failed: No URL returned" | |
exit 1 | |
} | |
} catch { | |
Write-Error "Upload failed: $_" | |
exit 1 | |
} | |
artifacts: | |
reports: | |
dotenv: upload_apk.env | |
upload_aab: | |
stage: upload | |
tags: | |
- winserver | |
script: | |
- echo "Uploading AAB file..." | |
- echo "Current Directory $(Get-Location)" | |
- $VERSION = Get-Content -Path "mainProjectVersion.txt" | |
- if (-not $VERSION) { | |
Write-Error "Version not found in mainProjectVersion.txt" | |
exit 1 | |
} | |
- $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]" | |
- $headers.Add("x-api-key", "apikey") | |
- $headers.Add("Albumuuid", "uuid") | |
- $AAB_FILE = "../outFile/DotaDiviner-$VERSION.aab" | |
- echo "AAB_FILE is $AAB_FILE" | |
- if (!(Test-Path $AAB_FILE)) { Write-Error "AAB file not found $AAB_FILE"; exit 1 } | |
- $multipartContent = [System.Net.Http.MultipartFormDataContent]::new() | |
- echo "Current Directory $(Get-Location)" | |
- $fullPathAab = (Get-Item "../outFile/DotaDiviner-$VERSION.aab").FullName | |
- echo "Full path $fullPathAab" | |
- | | |
if (!(Test-Path $fullPathAab)) { | |
Write-Error "File not found: $fullPathAab" | |
exit 1 | |
} | |
- $FileStream = [System.IO.FileStream]::new($fullPathAab, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read) | |
- $fileContent = [System.Net.Http.StreamContent]::new($FileStream) | |
- $fileHeader = [System.Net.Http.Headers.ContentDispositionHeaderValue]::new("form-data") | |
- $fileHeader.Name = "file" | |
- $fileHeader.FileName = (Split-Path $fullPathAab -Leaf) | |
- $fileContent.Headers.ContentDisposition = $fileHeader | |
- $multipartContent.Add($fileContent) | |
- | | |
try { | |
$response = Invoke-RestMethod 'https://chibisafe' -Method 'POST' -Headers $headers -Body $multipartContent | |
echo "Response from API: $($response | ConvertTo-Json -Depth 10)" | |
if ($response -and $response.url) { | |
$UPLOAD_URL_AAB = $response.url | |
echo "UPLOAD_URL_AAB=$UPLOAD_URL_AAB" | |
# Записываем в переменную окружения GitLab | |
echo "UPLOAD_URL_AAB=$UPLOAD_URL_AAB" | Out-File -FilePath "$CI_PIPELINE_ID.env" -Append | |
Write-Output "Upload successful: $UPLOAD_URL_AAB" | |
echo "UPLOAD_URL_AAB=$UPLOAD_URL_AAB" | Out-File -FilePath "upload_aab.env" | |
} else { | |
Write-Error "Upload failed: No URL returned" | |
exit 1 | |
} | |
} catch { | |
Write-Error "Upload failed: $_" | |
exit 1 | |
} | |
artifacts: | |
reports: | |
dotenv: upload_aab.env | |
upload_msi: | |
stage: upload | |
tags: | |
- winserver | |
script: | |
- echo "Uploading MSI file..." | |
- echo "Current Directory $(Get-Location)" | |
- $VERSION = Get-Content -Path "mainProjectVersion.txt" | |
- if (-not $VERSION) { | |
Write-Error "Version not found in mainProjectVersion.txt" | |
exit 1 | |
} | |
- $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]" | |
- $headers.Add("x-api-key", "apikey") | |
- $headers.Add("Albumuuid", "uuid") | |
- $MSI_FILE = "../outFile/DotaDiviner-$VERSION.msi" | |
- echo "MSI_FILE is $MSI_FILE" | |
- if (!(Test-Path $MSI_FILE)) { Write-Error "MSI file not found $MSI_FILE"; exit 1 } | |
- $multipartContent = [System.Net.Http.MultipartFormDataContent]::new() | |
- echo "Current Directory $(Get-Location)" | |
- $fullPathMsi = (Get-Item "../outFile/DotaDiviner-$VERSION.msi").FullName | |
- echo "Full path $fullPathMsi" | |
- | | |
if (!(Test-Path $fullPathMsi)) { | |
Write-Error "File not found: $fullPathMsi" | |
exit 1 | |
} | |
- $FileStream = [System.IO.FileStream]::new($fullPathMsi, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read) | |
- $fileContent = [System.Net.Http.StreamContent]::new($FileStream) | |
- $fileHeader = [System.Net.Http.Headers.ContentDispositionHeaderValue]::new("form-data") | |
- $fileHeader.Name = "file" | |
- $fileHeader.FileName = (Split-Path $fullPathMsi -Leaf) | |
- $fileContent.Headers.ContentDisposition = $fileHeader | |
- $multipartContent.Add($fileContent) | |
- | | |
try { | |
$response = Invoke-RestMethod 'https://chibisafe' -Method 'POST' -Headers $headers -Body $multipartContent | |
echo "Response from API: $($response | ConvertTo-Json -Depth 10)" | |
if ($response -and $response.url) { | |
$UPLOAD_URL_MSI = $response.url | |
echo "UPLOAD_URL_MSI=$UPLOAD_URL_MSI" | |
# Записываем в переменную окружения GitLab | |
echo "UPLOAD_URL_MSI=$UPLOAD_URL_MSI" | Out-File -FilePath "$CI_PIPELINE_ID.env" -Append | |
Write-Output "Upload successful: $UPLOAD_URL_MSI" | |
echo "UPLOAD_URL_MSI=$UPLOAD_URL_MSI" | Out-File -FilePath "upload_msi.env" | |
} else { | |
Write-Error "Upload failed: No URL returned" | |
exit 1 | |
} | |
} catch { | |
Write-Error "Upload failed: $_" | |
exit 1 | |
} | |
- echo "Uploading MSI file to remote server..." | |
- where ssh | |
- $KEY_FILE = New-TemporaryFile | |
- $KEY_FILE_PATH = $KEY_FILE.FullName | |
- $SSH_PRIVATE_KEY_ORACLE_MICRO_FIRST | Out-File -Encoding ascii -FilePath $KEY_FILE_PATH | |
- icacls $KEY_FILE_PATH /inheritance:r /grant *S-1-5-32-544:F | |
- scp -o StrictHostKeyChecking=no -i "$KEY_FILE_PATH" "$fullPathMsi" "ubuntu@ipaddr:/var/www/appdownloads/DotaDiviner.msi" | |
- Remove-Item -Force $KEY_FILE_PATH | |
artifacts: | |
reports: | |
dotenv: upload_msi.env | |
upload_ios: | |
stage: upload | |
tags: | |
- macos-mini | |
before_script: [] | |
script: | | |
xcrun altool --upload-app \ | |
--type ios \ | |
--file "outIos/ipa/Dota Diviner.ipa" \ | |
--username "[email protected]" \ | |
--password "xxxx-xxxx-xxxx-xxxx" | |
echo "iOS app uploaded to App Store Connect successfully" | |
dependencies: | |
- build_ios | |
only: | |
- master | |
upload_macos: | |
stage: upload | |
tags: | |
- macos-mini | |
before_script: [] | |
script: | | |
echo "Uploading macOS app to App Store Connect" | |
export VERSION=$(cat mainProjectVersion.txt) | |
# Проверяем существование директории (сначала пробуем main-release, потом main) | |
PKG_DIR="" | |
if [ -d "composeApp/build/compose/binaries/main-release/pkg" ]; then | |
PKG_DIR="composeApp/build/compose/binaries/main-release/pkg" | |
echo "Found pkg directory: $PKG_DIR" | |
elif [ -d "composeApp/build/compose/binaries/main/pkg" ]; then | |
PKG_DIR="composeApp/build/compose/binaries/main/pkg" | |
echo "Found pkg directory: $PKG_DIR" | |
else | |
echo "ERROR: Neither main-release nor main pkg directory exists" | |
echo "Available directories:" | |
find composeApp/build -name "*.pkg" -type f 2>/dev/null || echo "No .pkg files found" | |
find composeApp/build -type d -name "*pkg*" 2>/dev/null || echo "No pkg directories found" | |
exit 1 | |
fi | |
PKG_FILE=$(find "$PKG_DIR" -name "DotaDiviner-*.pkg" | head -n 1) | |
if [ -z "$PKG_FILE" ]; then | |
echo "ERROR: No .pkg file found in $PKG_DIR" | |
echo "Directory contents:" | |
ls -la "$PKG_DIR/" || echo "Directory does not exist" | |
exit 1 | |
fi | |
echo "Found PKG file: $PKG_FILE" | |
/usr/bin/xcrun altool --upload-app -f "$PKG_FILE" -t macos -u "[email protected]" -p "xxxx-xxxx-xxxx-xxxx" --show-progress --verbose | |
echo "Релиз успешно завершен!" | |
dependencies: | |
- build_macos | |
only: | |
- master | |
# upload_wasm: | |
# stage: upload | |
# tags: | |
# - winserver | |
# script: | |
# - echo "Uploading WASM file..." | |
# - echo "Current Directory $(Get-Location)" | |
# - $VERSION = Get-Content -Path "mainProjectVersion.txt" | |
# - if (-not $VERSION) { | |
# Write-Error "Version not found in mainProjectVersion.txt" | |
# exit 1 | |
# } | |
# - $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]" | |
# - $headers.Add("x-api-key", "apikey") | |
# - $headers.Add("Albumuuid", "uuid") | |
# - $WASM_FILE = "../outFile/DotaDiviner-$VERSION.zip" | |
# - echo "WASM_FILE is $WASM_FILE" | |
# - if (!(Test-Path $WASM_FILE)) { Write-Error "WASM file not found $WASM_FILE"; exit 1 } | |
# - $multipartContent = [System.Net.Http.MultipartFormDataContent]::new() | |
# - echo "Current Directory $(Get-Location)" | |
# - $fullPathWasm = (Get-Item "../outFile/DotaDiviner-$VERSION.zip").FullName | |
# - echo "Full path $fullPathWasm" | |
# - | | |
# if (!(Test-Path $fullPathWasm)) { | |
# Write-Error "File not found: $fullPathWasm" | |
# exit 1 | |
# } | |
# - $FileStream = [System.IO.FileStream]::new($fullPathWasm, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read) | |
# - $fileContent = [System.Net.Http.StreamContent]::new($FileStream) | |
# - $fileHeader = [System.Net.Http.Headers.ContentDispositionHeaderValue]::new("form-data") | |
# - $fileHeader.Name = "file" | |
# - $fileHeader.FileName = (Split-Path $fullPathWasm -Leaf) | |
# - $fileContent.Headers.ContentDisposition = $fileHeader | |
# - $multipartContent.Add($fileContent) | |
# - | | |
# try { | |
# $response = Invoke-RestMethod 'https://chibisafe' -Method 'POST' -Headers $headers -Body $multipartContent | |
# echo "Response from API: $($response | ConvertTo-Json -Depth 10)" | |
# if ($response -and $response.url) { | |
# $UPLOAD_URL_WASM = $response.url | |
# echo "UPLOAD_URL_WASM=$UPLOAD_URL_WASM" | |
# # Записываем в переменную окружения GitLab | |
# echo "UPLOAD_URL_WASM=$UPLOAD_URL_WASM" | Out-File -FilePath "$CI_PIPELINE_ID.env" -Append | |
# Write-Output "Upload successful: $UPLOAD_URL_WASM" | |
# echo "UPLOAD_URL_WASM=$UPLOAD_URL_WASM" | Out-File -FilePath "upload_wasm.env" | |
# } else { | |
# Write-Error "Upload failed: No URL returned" | |
# exit 1 | |
# } | |
# } catch { | |
# Write-Error "Upload failed: $_" | |
# exit 1 | |
# } | |
# artifacts: | |
# reports: | |
# dotenv: upload_wasm.env | |
upload_wasm_on_macos: | |
stage: upload | |
tags: | |
- macos-mini | |
before_script: [ ] | |
script: | |
- echo "Uploading WASM file..." | |
- echo "Current Directory $(pwd)" | |
- VERSION=$(cat mainProjectVersion.txt) | |
- if [ -z "$VERSION" ]; then | |
echo "Version not found in mainProjectVersion.txt" >&2; | |
exit 1; | |
fi | |
- WASM_FILE="../outFile/DotaDiviner-$VERSION.zip" | |
- echo "WASM_FILE is $WASM_FILE" | |
- | | |
if [ ! -f "$WASM_FILE" ]; then | |
echo "WASM file not found: $WASM_FILE" >&2; | |
exit 1; | |
fi | |
- echo "Current Directory $(pwd)" | |
- FULL_PATH_WASM=$(realpath "$WASM_FILE") | |
- echo "Full path $FULL_PATH_WASM" | |
# Выполняем multipart-загрузку через curl | |
- | | |
RESPONSE=$(curl -s -w "%{http_code}" -o response.json -X POST "https://chibisafe" \ | |
-H "x-api-key: apikey" \ | |
-H "Albumuuid: uuid" \ | |
-F "file=@$FULL_PATH_WASM") | |
- 'echo "HTTP status: $RESPONSE"' | |
- echo "API response:" | |
- cat response.json | |
- if [ "$RESPONSE" -ne 200 ]; then | |
echo "Upload failed with HTTP status $RESPONSE" >&2; | |
exit 1; | |
fi | |
- UPLOAD_URL_WASM=$(jq -r '.url' response.json) | |
- | | |
if [ "$UPLOAD_URL_WASM" == "null" ] || [ -z "$UPLOAD_URL_WASM" ]; then | |
echo "Upload failed: No URL returned" >&2; | |
exit 1; | |
fi | |
- echo "UPLOAD_URL_WASM=$UPLOAD_URL_WASM" | |
- echo "UPLOAD_URL_WASM=$UPLOAD_URL_WASM" >> upload_wasm.env | |
artifacts: | |
reports: | |
dotenv: upload_wasm.env | |
#upload_js: | |
# stage: upload | |
# tags: | |
# - winserver | |
# script: | |
# - echo "Uploading JS file..." | |
# - echo "Current Directory $(Get-Location)" | |
# - $VERSION = Get-Content -Path "mainProjectVersion.txt" | |
# - if (-not $VERSION) { | |
# Write-Error "Version not found in mainProjectVersion.txt" | |
# exit 1 | |
# } | |
# - $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]" | |
# - $headers.Add("x-api-key", "apikey") | |
# - $headers.Add("Albumuuid", "uuid") | |
# - $JS_FILE = "../outFile/DotaDivinerJs-$VERSION.zip" | |
# - echo "JS_FILE is $JS_FILE" | |
# - if (!(Test-Path $JS_FILE)) { Write-Error "JS file not found $JS_FILE"; exit 1 } | |
# - $multipartContent = [System.Net.Http.MultipartFormDataContent]::new() | |
# - echo "Current Directory $(Get-Location)" | |
# - $fullPathJS = (Get-Item "../outFile/DotaDivinerJs-$VERSION.zip").FullName | |
# - echo "Full path $fullPathJS" | |
# - | | |
# if (!(Test-Path $fullPathJS)) { | |
# Write-Error "File not found: $fullPathJS" | |
# exit 1 | |
# } | |
# | |
# - $FileStream = [System.IO.FileStream]::new($fullPathJS, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read) | |
# - $fileContent = [System.Net.Http.StreamContent]::new($FileStream) | |
# - $fileHeader = [System.Net.Http.Headers.ContentDispositionHeaderValue]::new("form-data") | |
# - $fileHeader.Name = "file" | |
# - $fileHeader.FileName = (Split-Path $fullPathJS -Leaf) | |
# - $fileContent.Headers.ContentDisposition = $fileHeader | |
# - $multipartContent.Add($fileContent) | |
# - | | |
# try { | |
# $response = Invoke-RestMethod 'https://chibisafe' -Method 'POST' -Headers $headers -Body $multipartContent | |
# | |
# echo "Response from API: $($response | ConvertTo-Json -Depth 10)" | |
# | |
# if ($response -and $response.url) { | |
# $UPLOAD_URL_JS = $response.url | |
# echo "UPLOAD_URL_JS=$UPLOAD_URL_JS" | |
# | |
# # Записываем в переменную окружения GitLab | |
# echo "UPLOAD_URL_JS=$UPLOAD_URL_JS" | Out-File -FilePath "$CI_PIPELINE_ID.env" -Append | |
# Write-Output "Upload successful: $UPLOAD_URL_JS" | |
# echo "UPLOAD_URL_JS=$UPLOAD_URL_JS" | Out-File -FilePath "upload_js.env" | |
# } else { | |
# Write-Error "Upload failed: No URL returned" | |
# exit 1 | |
# } | |
# } catch { | |
# Write-Error "Upload failed: $_" | |
# exit 1 | |
# } | |
# artifacts: | |
# reports: | |
# dotenv: upload_js.env | |
upload_js_on_macos: | |
stage: upload | |
tags: | |
- macos-mini | |
before_script: [ ] | |
script: | |
- echo "Uploading JS file..." | |
- echo "Current Directory $(pwd)" | |
- VERSION=$(cat mainProjectVersion.txt) | |
- if [ -z "$VERSION" ]; then | |
echo "Version not found in mainProjectVersion.txt" >&2; | |
exit 1; | |
fi | |
- $JS_FILE="../outFile/DotaDivinerJs-$VERSION.zip" | |
- echo "JS_FILE is $JS_FILE" | |
- | | |
if [ ! -f "$JS_FILE" ]; then | |
echo "JS file not found: $JS_FILE" >&2; | |
exit 1; | |
fi | |
- echo "Current Directory $(pwd)" | |
- FULL_PATH_JS=$(realpath "$JS_FILE") | |
- echo "Full path $FULL_PATH_JS" | |
# Выполняем multipart-загрузку через curl | |
- | | |
RESPONSE=$(curl -s -w "%{http_code}" -o response.json -X POST "https://chibisafe" \ | |
-H "x-api-key: apikey" \ | |
-H "Albumuuid: uuid" \ | |
-F "file=@$FULL_PATH_JS") | |
- 'echo "HTTP status: $RESPONSE"' | |
- echo "API response:" | |
- cat response.json | |
- if [ "$RESPONSE" -ne 200 ]; then | |
echo "Upload failed with HTTP status $RESPONSE" >&2; | |
exit 1; | |
fi | |
- UPLOAD_URL_JS=$(jq -r '.url' response.json) | |
- | | |
if [ "$UPLOAD_URL_JS" == "null" ] || [ -z "$UPLOAD_URL_JS" ]; then | |
echo "Upload failed: No URL returned" >&2; | |
exit 1; | |
fi | |
- echo "UPLOAD_URL_JS=$UPLOAD_URL_JS" | |
- echo "UPLOAD_URL_JS=$UPLOAD_URL_JS" >> upload_js.env | |
artifacts: | |
reports: | |
dotenv: upload_js.env | |
create_release: | |
stage: create_release | |
tags: | |
- winserver | |
script: | |
- echo "Creating or updating GitLab Release..." | |
- $VERSION = Get-Content -Path "mainProjectVersion.txt" | |
- $VERSION_COMMITHASH = $(git rev-parse --short HEAD) | |
- $VERSION_TAG = "$VERSION" + "_" + "$VERSION_COMMITHASH" | |
- echo "VERSION_TAG=$VERSION_TAG" >> build.env | |
- $PIPELINE_ID = $env:CI_PIPELINE_ID | |
- $DATE = Get-Date -Format "dd-MM-yyyy HH:mm:ss" | |
- $DESCRIPTION = "Version $VERSION`nCommit $VERSION_COMMITHASH`nPipeline ID $PIPELINE_ID`nDate $DATE" | |
- $RELEASE_TAG = "$VERSION_TAG" | |
- echo "RELEASE_TAG=$RELEASE_TAG" | Out-File -FilePath "create_release.env" | |
- Write-Host "Ищем релиз с тегом $VERSION_TAG" | |
- | | |
try { | |
$response = Invoke-RestMethod -Uri "https://gitlab.example.com/api/v4/projects/*id*/releases/$VERSION_TAG" ` | |
-Method GET ` | |
-Headers @{"PRIVATE-TOKEN" = "glpat-token"} | |
} catch { | |
if ($_.Exception.Response.StatusCode -eq 404) { | |
Write-Host "Релиз не найден (404). Создадим новый." | |
$response = $null | |
} else { | |
throw $_ # Прочие ошибки пробрасываем дальше | |
} | |
} | |
- Write-Host "GitLab API response $($response | ConvertTo-Json -Depth 10)" | |
# Если релиз существует, добавляем файл, иначе создаем новый релиз | |
- | | |
if ($response) { | |
Write-Host "Релиз с версией $VERSION_TAG уже существует. " | |
$RELEASE_ID = $response[0].id | |
} else { | |
Write-Host "Релиз с версией $VERSION_TAG не существует. Создаем новый релиз..." | |
$CREATE_RELEASE_DATA = @{ | |
"tag_name" = "$VERSION_TAG"; | |
"name" = "Release $VERSION ($VERSION_COMMITHASH)"; | |
"description" = "$DESCRIPTION"; | |
"ref" = "master" | |
} | |
$CREATE_RELEASE_RESPONSE = Invoke-RestMethod -Uri "https://gitlab.example.com/api/v4/projects/*id*/releases" ` | |
-Method POST ` | |
-Headers @{"PRIVATE-TOKEN" = "glpat-token"; "Content-Type" = "application/json"} ` | |
-Body ($CREATE_RELEASE_DATA | ConvertTo-Json -Depth 10) | |
Write-Host "Релиз $VERSION_TAG успешно создан." | |
} | |
artifacts: | |
reports: | |
dotenv: create_release.env | |
update_apk: | |
stage: update_files | |
tags: | |
- winserver | |
needs: | |
- job: upload_apk | |
artifacts: true | |
- create_release | |
script: | |
- Write-Output "$UPLOAD_URL_APK" | |
- Write-Output "$VERSION_TAG" | |
- echo "$VERSION_TAG" | |
- echo "Adding APK to GitLab Release..." | |
- echo "Release tag $RELEASE_TAG" | |
- if (!$RELEASE_TAG) { Write-Error "RELEASE_TAG is missing"; exit 1 } | |
- $UPLOAD_URL_APK = $env:UPLOAD_URL_APK | |
- if (!$UPLOAD_URL_APK) { Write-Error "UPLOAD_URL_APK is missing"; exit 1 } | |
- | | |
Invoke-RestMethod -Uri "https://gitlab.example.com/api/v4/projects/*id*/releases/$RELEASE_TAG/assets/links" ` | |
-Method POST ` | |
-Headers @{"PRIVATE-TOKEN" = "glpat-token"} ` | |
-Body @{ | |
name = "APK app" | |
url = "$UPLOAD_URL_APK" | |
} | |
- Write-Output "APK added to release successfully." | |
dependencies: | |
- create_release # Указываем зависимость от предыдущего джоба, чтобы использовать его артефакты | |
- upload_apk | |
update_aab: | |
stage: update_files | |
tags: | |
- winserver | |
needs: | |
- job: upload_aab # Зависимость от upload_wasm | |
artifacts: true | |
- create_release | |
script: | |
- Write-Output "$UPLOAD_URL_AAB" | |
- Write-Output "$VERSION_TAG" | |
- echo "$VERSION_TAG" | |
- echo "Adding AAB to GitLab Release..." | |
- echo "Release tag $RELEASE_TAG" | |
- if (!$RELEASE_TAG) { Write-Error "RELEASE_TAG is missing"; exit 1 } | |
- $UPLOAD_URL_AAB = $env:UPLOAD_URL_AAB | |
- if (!$UPLOAD_URL_AAB) { Write-Error "UPLOAD_URL_AAB is missing"; exit 1 } | |
- | | |
Invoke-RestMethod -Uri "https://gitlab.example.com/api/v4/projects/*id*/releases/$RELEASE_TAG/assets/links" ` | |
-Method POST ` | |
-Headers @{"PRIVATE-TOKEN" = "glpat-token"} ` | |
-Body @{ | |
name = "AAB app" | |
url = "$UPLOAD_URL_AAB" | |
} | |
- Write-Output "AAB added to release successfully." | |
dependencies: | |
- create_release # Указываем зависимость от предыдущего джоба, чтобы использовать его артефакты | |
- upload_aab | |
update_msi: | |
stage: update_files | |
tags: | |
- winserver | |
needs: | |
- job: upload_msi # Зависимость от upload_wasm | |
artifacts: true | |
- create_release | |
script: | |
- Write-Output "$UPLOAD_URL_MSI" | |
- Write-Output "$VERSION_TAG" | |
- echo "$VERSION_TAG" | |
- echo "Adding MSI to GitLab Release..." | |
- echo "Release tag $RELEASE_TAG" | |
- if (!$RELEASE_TAG) { Write-Error "RELEASE_TAG is missing"; exit 1 } | |
- $UPLOAD_URL_MSI = $env:UPLOAD_URL_MSI | |
- if (!$UPLOAD_URL_MSI) { Write-Error "UPLOAD_URL_MSI is missing"; exit 1 } | |
- | | |
Invoke-RestMethod -Uri "https://gitlab.example.com/api/v4/projects/*id*/releases/$RELEASE_TAG/assets/links" ` | |
-Method POST ` | |
-Headers @{"PRIVATE-TOKEN" = "glpat-token"} ` | |
-Body @{ | |
name = "MSI app" | |
url = "$UPLOAD_URL_MSI" | |
} | |
- Write-Output "MSI added to release successfully." | |
dependencies: | |
- create_release # Указываем зависимость от предыдущего джоба, чтобы использовать его артефакты | |
- upload_msi | |
# update_wasm: | |
# stage: update_files | |
# tags: | |
# - winserver | |
# needs: | |
# - job: upload_wasm # Зависимость от upload_wasm | |
# artifacts: true | |
# - create_release | |
# script: | |
# - Write-Output "$VERSION_TAG" | |
# - echo "$VERSION_TAG" | |
# - echo "Adding WASM to GitLab Release..." | |
# - echo "Release tag $RELEASE_TAG" | |
# - if (!$RELEASE_TAG) { Write-Error "RELEASE_TAG is missing"; exit 1 } | |
# - $UPLOAD_URL_WASM = $env:UPLOAD_URL_WASM | |
# - if (!$UPLOAD_URL_WASM) { Write-Error "UPLOAD_URL_WASM is missing"; exit 1 } | |
# - | | |
# Invoke-RestMethod -Uri "https://gitlab.example.com/api/v4/projects/*id*/releases/$RELEASE_TAG/assets/links" ` | |
# -Method POST ` | |
# -Headers @{"PRIVATE-TOKEN" = "glpat-token"} ` | |
# -Body @{ | |
# name = "WASM app" | |
# url = "$UPLOAD_URL_WASM" | |
# } | |
# - Write-Output "WASM added to release successfully." | |
# dependencies: | |
# - create_release # Указываем зависимость от предыдущего джоба, чтобы использовать его артефакты | |
# - upload_wasm | |
update_wasm_on_macos: | |
stage: update_files | |
tags: | |
- macos-mini | |
needs: | |
- job: upload_wasm_on_macos # Зависимость от upload_wasm | |
artifacts: true | |
- create_release | |
before_script: [] | |
script: | |
- echo "$VERSION_TAG" | |
- echo "Adding WASM to GitLab Release..." | |
- 'echo "Release tag: $RELEASE_TAG"' | |
- if [ -z "$RELEASE_TAG" ]; then | |
echo "RELEASE_TAG is missing" >&2; | |
exit 1; | |
fi | |
- if [ -z "$UPLOAD_URL_WASM" ]; then | |
echo "UPLOAD_URL_WASM is missing" >&2; | |
exit 1; | |
fi | |
- echo "Uploading WASM link to release..." | |
- | | |
curl -s --request POST "https://gitlab.example.com/api/v4/projects/*id*/releases/$RELEASE_TAG/assets/links" \ | |
--header "PRIVATE-TOKEN: glpat-token" \ | |
--header "Content-Type: application/json" \ | |
--data "{ | |
\"name\": \"WASM app\", | |
\"url\": \"$UPLOAD_URL_WASM\" | |
}" | |
- echo "WASM added to release successfully." | |
dependencies: | |
- create_release | |
- upload_wasm_on_macos | |
#update_js: | |
# stage: update_files | |
# tags: | |
# - winserver | |
# needs: | |
# - job: upload_js # Зависимость от upload_wasm | |
# artifacts: true | |
# - create_release | |
# script: | |
# - Write-Output "$VERSION_TAG" | |
# - echo "$VERSION_TAG" | |
# - echo "Adding JS to GitLab Release..." | |
# - echo "Release tag $RELEASE_TAG" | |
# - if (!$RELEASE_TAG) { Write-Error "RELEASE_TAG is missing"; exit 1 } | |
# - $UPLOAD_URL_JS = $env:UPLOAD_URL_JS | |
# | |
# - if (!$UPLOAD_URL_JS) { Write-Error "UPLOAD_URL_JS is missing"; exit 1 } | |
# - | | |
# Invoke-RestMethod -Uri "https://gitlab.example.com/api/v4/projects/*id*/releases/$RELEASE_TAG/assets/links" ` | |
# -Method POST ` | |
# -Headers @{"PRIVATE-TOKEN" = "glpat-token"} ` | |
# -Body @{ | |
# name = "JS app" | |
# url = "$UPLOAD_URL_JS" | |
# } | |
# - Write-Output "JS added to release successfully." | |
# dependencies: | |
# - create_release # Указываем зависимость от предыдущего джоба, чтобы использовать его артефакты | |
# - upload_js | |
update_js_on_macos: | |
stage: update_files | |
tags: | |
- macos-mini | |
needs: | |
- job: upload_js_on_macos # Зависимость от upload_wasm | |
artifacts: true | |
- create_release | |
before_script: [ ] | |
script: | |
- echo "$VERSION_TAG" | |
- echo "Adding JS to GitLab Release..." | |
- 'echo "Release tag: $RELEASE_TAG"' | |
- if [ -z "$RELEASE_TAG" ]; then | |
echo "RELEASE_TAG is missing" >&2; | |
exit 1; | |
fi | |
- if [ -z "$UPLOAD_URL_JS" ]; then | |
echo "UPLOAD_URL_JS is missing" >&2; | |
exit 1; | |
fi | |
- echo "Uploading JS link to release..." | |
- | | |
curl -s --request POST "https://gitlab.example.com/api/v4/projects/*id*/releases/$RELEASE_TAG/assets/links" \ | |
--header "PRIVATE-TOKEN: glpat-token" \ | |
--header "Content-Type: application/json" \ | |
--data "{ | |
\"name\": \"JS app\", | |
\"url\": \"$UPLOAD_URL_JS\" | |
}" | |
- echo "JS added to release successfully." | |
dependencies: | |
- create_release # Указываем зависимость от предыдущего джоба, чтобы использовать его артефакты | |
- upload_js_on_macos |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment