From 750292bfba0d1fb903d3c44cbd22848495197e80 Mon Sep 17 00:00:00 2001 From: achiez Date: Fri, 7 Nov 2025 16:31:01 +0200 Subject: [PATCH] Prepare for 1.8.0 release: Simplified CI/CD and localization updates - Replaced old build-and-release.yml with a streamlined process in build-release.yml, simplifying release creation with dotnet publish, changelog conversion, and GitHub release automation. - Added prepare-release.yml to automate release preparation, including version extraction, update.xml generation, and tagging. - Introduced changelog for version 1.8.0 with a new HTML file (1.8.0.html) and external links to detailed updates. - Updated NebulaAuth.sln to include the new changelog file. - Refactored SetAccountPasswordsVM.cs to use localization for success messages and added a helper method for retrieving localized strings. - Enhanced localization.loc.json with new strings for SetAccountPasswordsVM and improved formatting by removing duplicates. - Improved changelog HTML structure and styles for better readability and mobile responsiveness. - Performed minor code cleanups and formatting adjustments. --- .github/workflows/build-and-release.yml | 108 ------------------ .github/workflows/build-release.yml | 78 +++++++++++++ .github/workflows/prepare-release.yml | 65 +++++++++++ NebulaAuth.sln | 1 + changelog/1.8.0.html | 80 +++++++++++++ .../ViewModel/Other/SetAccountPasswordsVM.cs | 10 +- src/NebulaAuth/localization.loc.json | 87 ++++++-------- 7 files changed, 270 insertions(+), 159 deletions(-) delete mode 100644 .github/workflows/build-and-release.yml create mode 100644 .github/workflows/build-release.yml create mode 100644 .github/workflows/prepare-release.yml create mode 100644 changelog/1.8.0.html diff --git a/.github/workflows/build-and-release.yml b/.github/workflows/build-and-release.yml deleted file mode 100644 index ae94a6c..0000000 --- a/.github/workflows/build-and-release.yml +++ /dev/null @@ -1,108 +0,0 @@ -name: Build and Release - -on: - push: - tags: - - '*' - -jobs: - build: - if: github.ref == 'refs/heads/master' - runs-on: windows-latest - - steps: - - name: Checkout code - uses: actions/checkout@v2 - - - name: Setup .NET - uses: actions/setup-dotnet@v1 - with: - dotnet-version: "8.x" - - - name: Restore dependencies - run: dotnet restore NebulaAuth.sln - - - name: Build - run: dotnet build NebulaAuth.sln --configuration Release - - - name: Get version from assembly - id: get-version - shell: pwsh - run: | - $content = Get-Content -Path "NebulaAuth/NebulaAuth.csproj" -Raw - $version = [regex]::Match($content, '(.*?)<\/AssemblyVersion>').Groups[1].Value - Write-Output "VERSION=$version" >> $env:GITHUB_ENV - - - name: Check if tag exists - id: tag_exists - run: | - if (git tag -l | Select-String -Pattern "^${env:VERSION}$") { - Write-Output "Version $env:VERSION already exists." - exit 1 - } - - - name: Check changelog - run: | - if (-not (Test-Path "changelog/${env:VERSION}.html")) { - Write-Output "Changelog file changelog/${env:VERSION}.html does not exist." - exit 1 - } - - - name: Insert date into changelog - run: | - $date = Get-Date -Format "dd.MM.yyyy" - (Get-Content "changelog/${env:VERSION}.html") -replace '(?<=
).*?(?=
)', $date | Set-Content "changelog/${env:VERSION}.html" - - - name: Extract changelog description - id: extract_description - run: | - $description = (Get-Content "changelog/${env:VERSION}.html" | Select-String -Pattern '(?<=
).*?(?=
)' | ForEach-Object { $_.Matches.Value }) -replace '', "`n" - Write-Output "DESCRIPTION=$description" >> $env:GITHUB_ENV - - - name: Create ZIP - run: | - New-Item -ItemType Directory -Path release -Force - Compress-Archive -Path NebulaAuth/bin/Release -DestinationPath release/NebulaAuth.${env:VERSION}.zip - - - name: Create GitHub Release - id: create_release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ env.VERSION }} - release_name: NebulaAuth ${{ env.VERSION }} - body: | - ${{ env.DESCRIPTION }} - draft: false - prerelease: false - - - name: Upload Release Asset - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: release/NebulaAuth.${{ env.VERSION }}.zip - asset_name: NebulaAuth.${{ env.VERSION }}.zip - asset_content_type: application/zip - - - name: Update XML and Changelog html - shell: pwsh - run: | - $xmlContent = @" - - - ${env:VERSION}.0 - https://github.com/${env:GITHUB_REPOSITORY}/releases/download/${env:VERSION}/NebulaAuth.${env:VERSION}.zip - https://achiez.github.io/NebulaAuth-Steam-Desktop-Authenticator-by-Achies/changelog/${env:VERSION}.html - false - - "@ - $xmlContent | Out-File -FilePath update.xml -Encoding UTF8 -Force - - git config --global user.name 'github-actions' - git config --global user.email 'github-actions@github.com' - git add changelog/${env:VERSION}.html update.xml - git commit -m "Update version to ${env:VERSION} and add changelog" - git push origin master diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml new file mode 100644 index 0000000..2d1c57d --- /dev/null +++ b/.github/workflows/build-release.yml @@ -0,0 +1,78 @@ +name: Publish release + +on: + push: + tags: + - '*' + workflow_dispatch: + +jobs: + release: + runs-on: windows-latest + permissions: + contents: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Extract version + id: ver + run: echo "version=${GITHUB_REF_NAME}" >> $GITHUB_OUTPUT + shell: bash + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '8.0.x' + + - name: Build NebulaAuth + run: dotnet publish src/NebulaAuth/NebulaAuth.csproj -c Release -o build + + - name: Package release + run: | + cd build + powershell Compress-Archive * "../NebulaAuth.${env:GITHUB_REF_NAME}.zip" + shell: pwsh + + - name: Install pandoc + run: | + choco install pandoc -y + + - name: Convert changelog HTML to Markdown (ul-only) + id: changelog + shell: bash + run: | + version="${{ steps.ver.outputs.version }}" + file="changelog/${version}.html" + echo "Looking for file: $file" + + if [ -f "$file" ]; then + echo "✅ File found, extracting
    section" + sed -n '/
      /,/<\/ul>/p' "$file" > body.html + + echo "Converting with pandoc..." + pandoc body.html -f html -t markdown --wrap=none -o changelog.md + + echo "-------- Converted changelog.md --------" + cat changelog.md + echo "----------------------------------------" + + echo "body<> $GITHUB_OUTPUT + cat changelog.md >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + else + echo "❌ Changelog not found for version $version" + echo "body=No changelog found for $version" >> $GITHUB_OUTPUT + fi + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ steps.ver.outputs.version }} + name: Release ${{ env.RELEASE_NAME }} + body: ${{ steps.changelog.outputs.body }} + files: | + NebulaAuth.${{ steps.ver.outputs.version }}.zip + env: + RELEASE_NAME: ${{ steps.ver.outputs.version }} diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml new file mode 100644 index 0000000..591e3b8 --- /dev/null +++ b/.github/workflows/prepare-release.yml @@ -0,0 +1,65 @@ +name: Prepare release + +on: + push: + branches: [ master ] + paths: + - 'src/NebulaAuth/NebulaAuth.csproj' + workflow_dispatch: + +jobs: + prepare: + runs-on: ubuntu-latest + permissions: + contents: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + token: ${{ secrets.PAT_TOKEN }} + + - name: Read version from csproj + id: ver + shell: bash + run: | + VERSION=$(grep -oPm1 "(?<=)[^<]+" src/NebulaAuth/NebulaAuth.csproj) + echo "Detected version $VERSION" + echo "version=$VERSION" >> $GITHUB_OUTPUT + + - name: Generate update.xml + run: | + cat > NebulaAuth/update.xml < + + ${{ steps.ver.outputs.version }} + https://github.com/${{ github.repository }}/releases/download/${{ steps.ver.outputs.version }}/NebulaAuth.${{ steps.ver.outputs.version }}.zip + https://achiez.github.io/${{ github.repository }}/changelog/${{ steps.ver.outputs.version }}.html + false + + EOF + echo "Generated NebulaAuth/update.xml:" + cat NebulaAuth/update.xml + + - name: Check if update.xml changed + id: diff + run: | + if git diff --exit-code NebulaAuth/update.xml >/dev/null 2>&1; then + echo "no_changes=true" >> $GITHUB_OUTPUT + else + echo "no_changes=false" >> $GITHUB_OUTPUT + fi + + - name: Commit and tag + if: steps.diff.outputs.no_changes == 'false' + run: | + git config user.name "github-actions" + git config user.email "actions@github.com" + git add NebulaAuth/update.xml + git commit -m "chore(release): ${{ steps.ver.outputs.version }}" + git tag -a "${{ steps.ver.outputs.version }}" -m "Release ${{ steps.ver.outputs.version }}" + git push origin HEAD:master --tags + + - name: Skip message + if: steps.diff.outputs.no_changes == 'true' + run: echo "No changes in version or update.xml skipping release preparation." diff --git a/NebulaAuth.sln b/NebulaAuth.sln index 2ac2629..8959eed 100644 --- a/NebulaAuth.sln +++ b/NebulaAuth.sln @@ -23,6 +23,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "changelog", "changelog", "{ changelog\1.7.2.html = changelog\1.7.2.html changelog\1.7.3.html = changelog\1.7.3.html changelog\1.7.4.html = changelog\1.7.4.html + changelog\1.8.0.html = changelog\1.8.0.html EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SteamLibForked", "src\SteamLibForked\SteamLibForked.csproj", "{224F9DB0-3D20-A614-BA2A-12F22B13A2C6}" diff --git a/changelog/1.8.0.html b/changelog/1.8.0.html new file mode 100644 index 0000000..4e531c6 --- /dev/null +++ b/changelog/1.8.0.html @@ -0,0 +1,80 @@ + + + + + + Changelog + + + + +
      + +
      +
      Version 1.8.0
      +
      07.11.2025
      +
      +
        +
      • Major update: Full changelog is available here ENG | RUS
      • +
      +
      +
      +
      + + + \ No newline at end of file diff --git a/src/NebulaAuth/ViewModel/Other/SetAccountPasswordsVM.cs b/src/NebulaAuth/ViewModel/Other/SetAccountPasswordsVM.cs index a4cddfa..2ecaa59 100644 --- a/src/NebulaAuth/ViewModel/Other/SetAccountPasswordsVM.cs +++ b/src/NebulaAuth/ViewModel/Other/SetAccountPasswordsVM.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Threading.Tasks; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; +using NebulaAuth.Core; using NebulaAuth.Model; using SteamLibForked.Models.SteamIds; @@ -102,11 +103,11 @@ public partial class SetAccountPasswordsVM : ObservableObject if (success > 0 && errors == 0 && notFound == 0) { - Tip = "Успех"; + Tip = string.Format(GetLocalization("Success"), success); } else { - Tip = $"Успешно: {success}, Не найдено: {notFound}, Ошибки: {errors}"; + Tip = string.Format(GetLocalization("PartialSuccess"), success, notFound, errors); } } @@ -120,4 +121,9 @@ public partial class SetAccountPasswordsVM : ObservableObject { Tip = null; } + + private string GetLocalization(string key) + { + return LocManager.GetCodeBehindOrDefault(key, "SetAccountPasswordsVM", key); + } } \ No newline at end of file diff --git a/src/NebulaAuth/localization.loc.json b/src/NebulaAuth/localization.loc.json index 027789e..82b4ad9 100644 --- a/src/NebulaAuth/localization.loc.json +++ b/src/NebulaAuth/localization.loc.json @@ -808,12 +808,9 @@ "ua": "Відсутній RCode" }, "ConfirmRemovingAuthenticator": { - "ru": - "Вы точно уверены, что хотите удалить аутентификатор?\r\nПосле этого вы не сможете обмениваться, использовать торговую площадку 15 дней. Мафайл будет удалён навсегда", - "en": - "Are you sure you want to remove the authenticator?\r\nAfter that, you will not be able to trade or use the marketplace for 15 days. Mafile will be deleted permanently", - "ua": - "Ви точно впевнені, що хочете видалити автентифікатор?\r\nПісля цього ви не зможете обмінюватися, використовувати торгову площадку 15 днів. Мафайл буде видалено назавжди" + "ru": "Вы точно уверены, что хотите удалить аутентификатор?\r\nПосле этого вы не сможете обмениваться, использовать торговую площадку 15 дней. Мафайл будет удалён навсегда", + "en": "Are you sure you want to remove the authenticator?\r\nAfter that, you will not be able to trade or use the marketplace for 15 days. Mafile will be deleted permanently", + "ua": "Ви точно впевнені, що хочете видалити автентифікатор?\r\nПісля цього ви не зможете обмінюватися, використовувати торгову площадку 15 днів. Мафайл буде видалено назавжди" }, "AuthenticatorRemoved": { @@ -882,12 +879,9 @@ "ua": "помилки:" }, "RemoveMafileConfirmation": { - "ru": - "Удалить mafile?\r\nМафайл будет перемещен в папку 'mafiles_removed'\r\nЭто действие НЕ удаляет Steam Guard с аккаунта", - "en": - "Remove mafile?\r\nMafile will be moved to 'mafiles_removed' directory\r\nThis action will NOT remove the Steam Guard from the account", - "ua": - "Видалити mafile?\r\nМафайл буде переміщено у каталог 'mafiles_removed'\r\nЦя дія НЕ видаляє автентифікатор з облікового запису" + "ru": "Удалить mafile?\r\nМафайл будет перемещен в папку 'mafiles_removed'\r\nЭто действие НЕ удаляет Steam Guard с аккаунта", + "en": "Remove mafile?\r\nMafile will be moved to 'mafiles_removed' directory\r\nThis action will NOT remove the Steam Guard from the account", + "ua": "Видалити mafile?\r\nМафайл буде переміщено у каталог 'mafiles_removed'\r\nЦя дія НЕ видаляє автентифікатор з облікового запису" }, "CantRemoveAlreadyExist": { "ru": "Не удалось переместить mafile, возможно в папке уже существует мафайл с таким именем.", @@ -941,8 +935,7 @@ }, "CantDecryptPassword": { "en": "Can't decrypt password. Maybe password from this mafile was encrypted with another encryption password", - "ru": - "Не удалось расшифровать пароль. Возможно пароль из этого мафайла был зашифрован другим паролем шифрования", + "ru": "Не удалось расшифровать пароль. Возможно пароль из этого мафайла был зашифрован другим паролем шифрования", "ua": "Не вдалося розшифрувати пароль. Можливо пароль з цього мафайла був зашифрований іншим паролем шифрування" }, "CreateGroupTitle": { @@ -1213,10 +1206,8 @@ }, "InvalidStateWithStatus2": { "ru": "Неверное состояние (InvalidState) со статусом 2. Откройте ссылку на руководство сверху этого окна.", - "en": - "Invalid state (InvalidState) with status 2. Open link to the troubleshooting guide at the top of this window.", - "ua": - "Невірний стан (InvalidState) зі статусом 2. Відкрийте посилання на посібник з усунення несправностей у верхній частині цього вікна." + "en": "Invalid state (InvalidState) with status 2. Open link to the troubleshooting guide at the top of this window.", + "ua": "Невірний стан (InvalidState) зі статусом 2. Відкрийте посилання на посібник з усунення несправностей у верхній частині цього вікна." }, "GeneralFailure": { "ru": "General Failure", @@ -1265,8 +1256,7 @@ "Guard": { "ru": "Ошибка: Был запрошен вход с помощью Steam Guard. На аккаунте уже активирован мобильный аутентификатор", "en": "Error: Login with Steam Guard was requested. Mobile authenticator is already activated on the account", - "ua": - "Помилка: Був запрошений вхід за допомогою Steam Guard. На акаунті вже активовано мобільний автентифікатор" + "ua": "Помилка: Був запрошений вхід за допомогою Steam Guard. На акаунті вже активовано мобільний автентифікатор" }, "Unknown": { "ru": "Ошибка: Неизвестный тип аутентификации", @@ -1369,12 +1359,9 @@ "ua": "На пошту надіслано лист. Відкрийте посилання з листа, а потім натисніть — 'Продовжити'" }, "ClickOnEmailLinkRetry": { - "ru": - "Не удалось подтвердить переход по ссылке. Убедитесь, что вы открыли ссылку из письма, затем нажмите — 'Продолжить'", - "en": - "We couldn’t verify that you clicked the link. Make sure you opened the link from the email, then click 'Proceed'", - "ua": - "Не вдалося підтвердити перехід за посиланням. Переконайтесь, що ви відкрили посилання з листа, а потім натисніть — 'Продовжити'" + "ru": "Не удалось подтвердить переход по ссылке. Убедитесь, что вы открыли ссылку из письма, затем нажмите — 'Продолжить'", + "en": "We couldn’t verify that you clicked the link. Make sure you opened the link from the email, then click 'Proceed'", + "ua": "Не вдалося підтвердити перехід за посиланням. Переконайтесь, що ви відкрили посилання з листа, а потім натисніть — 'Продовжити'" }, "PhoneHint": { "ru": "На телефон {0} была отправлена СМС", @@ -1382,12 +1369,9 @@ "ua": "На телефон {0} було відправлено СМС" }, "EnterPhoneNumber": { - "ru": - "Введите номер в международном формате, только цифры (без '+', пробелов и скобок), или оставьте поле пустым, чтобы привязать без номера", - "en": - "Enter number in international format, digits only (no '+', spaces or brackets), or leave the field empty to link without a number", - "ua": - "Введіть номер у міжнародному форматі, лише цифри (без '+', пробілів і дужок), або залиште поле порожнім, щоб прив’язати без номера" + "ru": "Введите номер в международном формате, только цифры (без '+', пробелов и скобок), или оставьте поле пустым, чтобы привязать без номера", + "en": "Enter number in international format, digits only (no '+', spaces or brackets), or leave the field empty to link without a number", + "ua": "Введіть номер у міжнародному форматі, лише цифри (без '+', пробілів і дужок), або залиште поле порожнім, щоб прив’язати без номера" } }, "MafileMoverVM": { @@ -1412,11 +1396,9 @@ "ua": "RCode: {0}\r\nІм'я файлу: {1}.mafile" }, "GuardIsNotActive": { - "ru": - "Steam Guard установлен на данном аккаунте. Чтобы привязать mafile к аккаунту, воспользуйтесь окном \"Привязать\"", + "ru": "Steam Guard установлен на данном аккаунте. Чтобы привязать mafile к аккаунту, воспользуйтесь окном \"Привязать\"", "en": "Steam Guard is set on this account. To link mafile to the account, use the 'Link' window", - "ua": - "Steam Guard встановлено на цьому акаунті. Щоб прив'язати mafile до акаунту, скористайтеся вікном 'Прив'язати'" + "ua": "Steam Guard встановлено на цьому акаунті. Щоб прив'язати mafile до акаунту, скористайтеся вікном 'Прив'язати'" }, "SeemsNoPhoneNumber": { "en": "The account has no phone number linked, returned Fail code (2)", @@ -1451,12 +1433,9 @@ "ua": "Авто " }, "TimerPreventedOverlap": { - "ru": - "Авто: таймер подтверждений пытался начать новый цикл, когда предыдущий еще не завершился. Советуем увеличить задержку", - "en": - "Auto: confirmation timer tried to start new cycle when previous one was not finished yet. We recommend to increase delay", - "ua": - "Авто: таймер підтверджень намагався запустити новий цикл, коли попередній ще не закінчився. Рекомендуємо збільшити затримку" + "ru": "Авто: таймер подтверждений пытался начать новый цикл, когда предыдущий еще не завершился. Советуем увеличить задержку", + "en": "Auto: confirmation timer tried to start new cycle when previous one was not finished yet. We recommend to increase delay", + "ua": "Авто: таймер підтверджень намагався запустити новий цикл, коли попередній ще не закінчився. Рекомендуємо збільшити затримку" }, "FailedToLoadStorage": { "en": "Failed to load auto-confirm timers. File seems to be corrupted", @@ -1477,12 +1456,9 @@ "ua": "Всі мафайли успішно перейменовані ({0}).\r\nБуло створено резервну копію: {1}" }, "PartialSuccess": { - "en": - "Total mafiles: {0}\r\nRenamed: {1}\r\nConflicts: {2}\r\nErrors: {3}\r\n\r\nBackup of mafiles saved in file: {4}", - "ru": - "Всего мафайлов: {0}\r\nПереименовано: {1}\r\nКонфликты: {2}\r\nОшибок: {3}\r\n\r\nРезервная копия мафайлов сохранена в файле: {4}", - "ua": - "Всього мафайлів: {0}\r\nПерейменовано: {1}\r\nКонфлікти: {2}\r\nПомилок: {3}\r\n\r\nРезервна копія мафайлів збережена у файлі: {4}" + "en": "Total mafiles: {0}\r\nRenamed: {1}\r\nConflicts: {2}\r\nErrors: {3}\r\n\r\nBackup of mafiles saved in file: {4}", + "ru": "Всего мафайлов: {0}\r\nПереименовано: {1}\r\nКонфликты: {2}\r\nОшибок: {3}\r\n\r\nРезервная копия мафайлов сохранена в файле: {4}", + "ua": "Всього мафайлів: {0}\r\nПерейменовано: {1}\r\nКонфлікти: {2}\r\nПомилок: {3}\r\n\r\nРезервна копія мафайлів збережена у файлі: {4}" } } }, @@ -1499,7 +1475,20 @@ "ru": "Ошибка при загрузке настроек. Настройки были сброшены", "ua": "Помилка при завантаженні налаштувань. Налаштування були скинуті" } - } + }, + "SetAccountPasswordsVM": { + "Success": { + "en": "Passwords successfully set for {0} mafiles", + "ru": "Пароли успешно установлены для {0} мафайлов", + "ua": "Паролі успішно встановлені для {0} мафайлів" + }, + "PartialSuccess": { + "en": "Success: {0}, Not found: {1}, Errors: {2}", + "ru": "Успешно: {0}, Не найдено: {1}, Ошибки: {2}", + "ua": "Успішно: {0}, Не знайдено: {1}, Помилки: {2}" + + } + } }, "CantAlignTimeError": { "ru":