From 68eb16027c5c3ed8cf703c989613adc97425fb57 Mon Sep 17 00:00:00 2001 From: SlavaVlad Date: Wed, 24 Jun 2026 16:07:06 +0300 Subject: [PATCH] ci: migrate from GitHub Actions to Gitea Actions --- .gitea/workflows/build.yml | 49 +++++ .gitea/workflows/create-prerelease.yml | 86 ++++++++ .gitea/workflows/on-push-master.yml | 21 ++ .gitea/workflows/on-push-other-branch.yml | 15 ++ .gitea/workflows/on-push-pr.yml | 10 + .gitea/workflows/on-update-dot-gitea.yml | 20 ++ .gitea/workflows/publish-release.yml | 252 ++++++++++++++++++++++ .gitea/workflows/run-tests.yml | 44 ++++ .gitea/workflows/update-moonsharp.yml | 31 +++ README.md | 16 ++ 10 files changed, 544 insertions(+) create mode 100644 .gitea/workflows/build.yml create mode 100644 .gitea/workflows/create-prerelease.yml create mode 100644 .gitea/workflows/on-push-master.yml create mode 100644 .gitea/workflows/on-push-other-branch.yml create mode 100644 .gitea/workflows/on-push-pr.yml create mode 100644 .gitea/workflows/on-update-dot-gitea.yml create mode 100644 .gitea/workflows/publish-release.yml create mode 100644 .gitea/workflows/run-tests.yml create mode 100644 .gitea/workflows/update-moonsharp.yml diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml new file mode 100644 index 000000000..81ceb8566 --- /dev/null +++ b/.gitea/workflows/build.yml @@ -0,0 +1,49 @@ +name: Build + +on: + workflow_dispatch: + workflow_call: + inputs: + target: + required: true + type: string + +env: + CI_DIR: 717a3c49-f5dc-42eb-b332-fcf2988d00e3 + +jobs: + build: + runs-on: ubuntu-22.04 + steps: + - name: Checkout branch + uses: actions/checkout@v4 + with: + ref: ${{ inputs.target }} + submodules: recursive + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: | + 8.0.x + + - name: Run deploy script + run: | + set -e + shopt -s globstar nullglob + shopt -u dotglob + cd Deploy + git apply < ./patches/disable-interactivity.diff + git apply < ./patches/prevent-crash-on-missing-dir.diff + ./DeployAll.sh + + - name: Create tarball + run: | + mkdir -p "$CI_DIR" + tar -czf "$CI_DIR/build.tar.gz" -C Deploy/bin/content . + + - name: Upload tarball + uses: actions/upload-artifact@v4 + with: + name: build + path: ${{ env.CI_DIR }}/build.tar.gz diff --git a/.gitea/workflows/create-prerelease.yml b/.gitea/workflows/create-prerelease.yml new file mode 100644 index 000000000..67aeabf79 --- /dev/null +++ b/.gitea/workflows/create-prerelease.yml @@ -0,0 +1,86 @@ +name: Create pre-release + +on: + schedule: + - cron: "0 0 * * *" + workflow_dispatch: + +jobs: + check-if-release-needed: + runs-on: ubuntu-22.04 + outputs: + latest-commit-sha: ${{ steps.get-latest-commit.outputs.result }} + has-new-commits: ${{ steps.check-for-new-commits.outputs.has-new-commits }} + steps: + - name: Extract branch name + id: extract-branch-name + run: | + echo "result=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> "$GITHUB_OUTPUT" + - name: Sanity checks + if: ${{ github.event_name == 'workflow_dispatch' && steps.extract-branch-name.outputs.result != 'develop' }} + run: | + echo "::error::this workflow can only be run on the \"develop\" branch" + exit 1 + + - name: Get latest nightly-tagged commit + id: get-latest-tag + env: + CI_RELEASE_TOKEN: ${{ secrets.CI_RELEASE_TOKEN }} + run: | + api_url="${GITEA_API_URL:-https://git.illegalfiles.icu/api/v1}" + repo="${GITEA_REPOSITORY:-vlad.os/LuaCsForBarotraumaEP}" + + ref=$(curl -s -H "Authorization: token $CI_RELEASE_TOKEN" \ + "$api_url/repos/$repo/tags" | \ + jq -r '.[] | select(.name == "nightly") | .commit.sha // empty') + + if [[ -z "$ref" ]]; then + echo "result=tag-doesnt-exist" >> "$GITHUB_OUTPUT" + else + echo "result=$ref" >> "$GITHUB_OUTPUT" + fi + + - name: Get latest commit on dev branch + id: get-latest-commit + env: + CI_RELEASE_TOKEN: ${{ secrets.CI_RELEASE_TOKEN }} + run: | + api_url="${GITEA_API_URL:-https://git.illegalfiles.icu/api/v1}" + repo="${GITEA_REPOSITORY:-vlad.os/LuaCsForBarotraumaEP}" + + sha=$(curl -s -H "Authorization: token $CI_RELEASE_TOKEN" \ + "$api_url/repos/$repo/branches/develop" | \ + jq -r '.commit.id // empty') + + echo "result=$sha" >> "$GITHUB_OUTPUT" + + - name: Check for new commits + id: check-for-new-commits + if: ${{ steps.get-latest-tag.outputs.result != 'tag-doesnt-exist' }} + env: + LATEST_TAGGED_SHA: "${{ steps.get-latest-tag.outputs.result }}" + LATEST_SHA: "${{ steps.get-latest-commit.outputs.result }}" + run: | + if [[ -z "$LATEST_TAGGED_SHA" ]]; then + echo "::error::LATEST_TAGGED_SHA env var is invalid" + exit 1 + fi + if [[ -z "$LATEST_SHA" ]]; then + echo "::error::LATEST_TAGGED_SHA env var is invalid" + exit 1 + fi + + if [[ "$LATEST_TAGGED_SHA" == "$LATEST_SHA" ]]; then + echo "has-new-commits=false" >> "$GITHUB_OUTPUT" + else + echo "has-new-commits=true" >> "$GITHUB_OUTPUT" + fi + + publish-release: + needs: [check-if-release-needed] + if: ${{ needs.check-if-release-needed.outputs.has-new-commits == 'true' }} + uses: ./.gitea/workflows/publish-release.yml + with: + target: ${{ needs.check-if-release-needed.outputs.latest-commit-sha }} + tag: nightly + prerelease: true diff --git a/.gitea/workflows/on-push-master.yml b/.gitea/workflows/on-push-master.yml new file mode 100644 index 000000000..2f3cee28f --- /dev/null +++ b/.gitea/workflows/on-push-master.yml @@ -0,0 +1,21 @@ +name: On push to master branch + +on: + push: + branches: [master] + paths-ignore: + - ".gitea/**" + - ".github/**" + - "*.md" + +jobs: + run-tests: + uses: ./.gitea/workflows/run-tests.yml + with: + target: ${{ github.event.ref }} + + publish-release: + uses: ./.gitea/workflows/publish-release.yml + with: + target: ${{ github.event.ref }} + tag: latest diff --git a/.gitea/workflows/on-push-other-branch.yml b/.gitea/workflows/on-push-other-branch.yml new file mode 100644 index 000000000..b018fdfa4 --- /dev/null +++ b/.gitea/workflows/on-push-other-branch.yml @@ -0,0 +1,15 @@ +name: On push to a secondary branch + +on: + push: + branches-ignore: [master] + paths-ignore: + - ".gitea/**" + - ".github/**" + - "*.md" + +jobs: + run-tests: + uses: ./.gitea/workflows/run-tests.yml + with: + target: ${{ github.event.ref }} diff --git a/.gitea/workflows/on-push-pr.yml b/.gitea/workflows/on-push-pr.yml new file mode 100644 index 000000000..f25e31c9a --- /dev/null +++ b/.gitea/workflows/on-push-pr.yml @@ -0,0 +1,10 @@ +name: On push to a PR + +on: + pull_request: + +jobs: + run-tests-for-pr: + uses: ./.gitea/workflows/run-tests.yml + with: + target: ${{ github.event.pull_request.head.sha }} diff --git a/.gitea/workflows/on-update-dot-gitea.yml b/.gitea/workflows/on-update-dot-gitea.yml new file mode 100644 index 000000000..96c4ffed0 --- /dev/null +++ b/.gitea/workflows/on-update-dot-gitea.yml @@ -0,0 +1,20 @@ +name: On changes to .gitea + +on: + push: + paths: + - ".gitea/**" + +jobs: + lint-workflows: + runs-on: ubuntu-22.04 + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Validate YAML + run: | + for f in .gitea/workflows/*.yml; do + echo "Validating $f" + python3 -c "import yaml; yaml.safe_load(open('$f'))" || exit 1 + done diff --git a/.gitea/workflows/publish-release.yml b/.gitea/workflows/publish-release.yml new file mode 100644 index 000000000..06696c05c --- /dev/null +++ b/.gitea/workflows/publish-release.yml @@ -0,0 +1,252 @@ +name: Publish release + +on: + workflow_dispatch: + inputs: + target: + description: "The git ref to checkout, build from and release" + required: true + type: string + tag: + description: "The tag of the release" + required: true + type: string + prerelease: + description: "Prerelease" + required: false + default: false + type: boolean + workflow_call: + inputs: + target: + description: "The git ref to checkout, build from and release" + required: true + type: string + tag: + description: "The tag of the release" + required: true + type: string + prerelease: + description: "Prerelease" + required: false + default: false + type: boolean + +env: + CI_DIR: 2049ef39-42a2-46d2-b513-ee6d2e3a7b15 + RELEASES: | + windows:server:Windows/Server + linux:server:Linux/Server + mac:server:Mac/Server + windows:client:Windows/Client + linux:client:Linux/Client + mac:client:Mac/Client/Barotrauma.app/Contents/MacOS + ARCHIVE_BASE_NAME: luacsforbarotraumaEP + ARCHIVE_FILES_SERVER: | + DedicatedServer.deps.json + DedicatedServer.dll + DedicatedServer.pdb + Publicized/DedicatedServer.dll + ARCHIVE_FILES_CLIENT: | + Barotrauma.deps.json + Barotrauma.dll + Barotrauma.pdb + DedicatedServer.deps.json + DedicatedServer.dll + DedicatedServer.pdb + Publicized/Barotrauma.dll + Publicized/DedicatedServer.dll + ARCHIVE_FILES_SHARED: | + BarotraumaCore.dll + BarotraumaCore.pdb + Publicized/BarotraumaCore.dll + 0Harmony.dll + Sigil.dll + MoonSharp.Interpreter.dll + MoonSharp.VsCodeDebugger.dll + MonoMod.Backports.dll + MonoMod.Core.dll + MonoMod.RuntimeDetour.dll + MonoMod.ILHelpers.dll + MonoMod.Utils.dll + MonoMod.Iced.dll + Mono.Cecil.dll + Mono.Cecil.Mdb.dll + Mono.Cecil.Pdb.dll + Mono.Cecil.Rocks.dll + LightInject.dll + OneOf.dll + FluentResults.dll + Basic.Reference.Assemblies.Net80.dll + Microsoft.Extensions.Logging.Abstractions.dll + Microsoft.Toolkit.Diagnostics.dll + Microsoft.CodeAnalysis.CSharp.dll + Microsoft.CodeAnalysis.dll + System.Collections.Immutable.dll + System.Reflection.Metadata.dll + System.Runtime.CompilerServices.Unsafe.dll + mscordaccore_amd64_amd64_* + LocalMods/LuaCsForBarotrauma + +jobs: + build: + uses: ./.gitea/workflows/build.yml + with: + target: ${{ inputs.target }} + + publish-release: + runs-on: ubuntu-22.04 + needs: [build] + steps: + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + name: build + path: ${{ env.CI_DIR }} + + - name: Extract build artifacts + run: | + artifacts_dir="$(realpath -m "$CI_DIR/artifacts")" + mkdir -p "$artifacts_dir" + tar -xzf "$CI_DIR/build.tar.gz" -C "$artifacts_dir" + rm "$CI_DIR/build.tar.gz" + + - name: Create archives + run: | + set -e + shopt -s globstar nullglob + shopt -u dotglob + + lines_to_array() { + IFS=$'\n' readarray -td $'\n' "$1" <<< "${!1}" + } + + lines_to_array ARCHIVE_FILES_SHARED + lines_to_array ARCHIVE_FILES_CLIENT + lines_to_array ARCHIVE_FILES_SERVER + lines_to_array RELEASES + + artifacts_dir="$(realpath -m "$CI_DIR/artifacts")" + mkdir -p "$artifacts_dir" + + archives_dir="$(realpath -m "$CI_DIR/archives")" + mkdir -p "$archives_dir" + + refs_dir="$(realpath -m "$CI_DIR/refs")" + mkdir -p "${refs_dir}" + mkdir -p "${refs_dir}/Windows" + mkdir -p "${refs_dir}/Linux" + mkdir -p "${refs_dir}/OSX" + + cp "${artifacts_dir}/Windows/Client/Publicized/Barotrauma.dll" "${refs_dir}/Windows/Barotrauma.dll" + cp "${artifacts_dir}/Windows/Client/Publicized/DedicatedServer.dll" "${refs_dir}/Windows/DedicatedServer.dll" + cp "${artifacts_dir}/Windows/Client/Publicized/BarotraumaCore.dll" "${refs_dir}/Windows/BarotraumaCore.dll" + cp "${artifacts_dir}/Linux/Client/Publicized/Barotrauma.dll" "${refs_dir}/Linux/Barotrauma.dll" + cp "${artifacts_dir}/Linux/Client/Publicized/DedicatedServer.dll" "${refs_dir}/Linux/DedicatedServer.dll" + cp "${artifacts_dir}/Linux/Client/Publicized/BarotraumaCore.dll" "${refs_dir}/Linux/BarotraumaCore.dll" + cp "${artifacts_dir}/Mac/Client/Barotrauma.app/Contents/MacOS/Publicized/Barotrauma.dll" "${refs_dir}/OSX/Barotrauma.dll" + cp "${artifacts_dir}/Mac/Client/Barotrauma.app/Contents/MacOS/Publicized/DedicatedServer.dll" "${refs_dir}/OSX/DedicatedServer.dll" + cp "${artifacts_dir}/Mac/Client/Barotrauma.app/Contents/MacOS/Publicized/BarotraumaCore.dll" "${refs_dir}/OSX/BarotraumaCore.dll" + cp "${artifacts_dir}/Windows/Client/Publicized/MonoGame.Framework.Windows.NetStandard.dll" "${refs_dir}/MonoGame.Framework.Windows.NetStandard.dll" + cp "${artifacts_dir}/Linux/Client/Publicized/MonoGame.Framework.Linux.NetStandard.dll" "${refs_dir}/MonoGame.Framework.Linux.NetStandard.dll" + cp "${artifacts_dir}/Mac/Client/Barotrauma.app/Contents/MacOS/Publicized/MonoGame.Framework.MacOS.NetStandard.dll" "${refs_dir}/MonoGame.Framework.MacOS.NetStandard.dll" + cp "${artifacts_dir}/Windows/Client/Publicized/0Harmony.dll" "${refs_dir}/0Harmony.dll" + cp "${artifacts_dir}/Windows/Client/Publicized/MonoMod.Utils.dll" "${refs_dir}/MonoMod.Utils.dll" + cp "${artifacts_dir}/Windows/Client/Publicized/MonoMod.RuntimeDetour.dll" "${refs_dir}/MonoMod.RuntimeDetour.dll" + cp "${artifacts_dir}/Windows/Client/Publicized/MonoMod.ILHelpers.dll" "${refs_dir}/MonoMod.ILHelpers.dll" + cp "${artifacts_dir}/Windows/Client/Publicized/MonoMod.Iced.dll" "${refs_dir}/MonoMod.Iced.dll" + cp "${artifacts_dir}/Windows/Client/Publicized/MonoMod.Backports.dll" "${refs_dir}/MonoMod.Backports.dll" + cp "${artifacts_dir}/Windows/Client/Publicized/Farseer.NetStandard.dll" "${refs_dir}/Farseer.NetStandard.dll" + cp "${artifacts_dir}/Windows/Client/Publicized/Lidgren.NetStandard.dll" "${refs_dir}/Lidgren.NetStandard.dll" + cp "${artifacts_dir}/Windows/Client/Publicized/Mono.Cecil.dll" "${refs_dir}/Mono.Cecil.dll" + cp "${artifacts_dir}/Windows/Client/Publicized/MoonSharp.Interpreter.dll" "${refs_dir}/MoonSharp.Interpreter.dll" + cp "${artifacts_dir}/Windows/Client/Publicized/XNATypes.dll" "${refs_dir}/XNATypes.dll" + cd "${refs_dir}" + zip -r "${archives_dir}/${ARCHIVE_BASE_NAME}_refs.zip" . + + for i in "${!RELEASES[@]}"; do + [[ -z "${RELEASES[i]}" ]] && continue + ( + IFS=':' read platform side publish_dir _rest <<< "${RELEASES[i]}" + cd "${artifacts_dir}/${publish_dir}" + + echo "Creating build_${platform}_${side}.zip" + zip --must-match -qr "${archives_dir}/${ARCHIVE_BASE_NAME}_build_${platform}_${side}.zip" * + + echo "Creating build_${platform}_${side}.tar.gz" + tar -czf "${archives_dir}/${ARCHIVE_BASE_NAME}_build_${platform}_${side}.tar.gz" \ + --owner=0 --group=0 \ + * + + if [[ "$side" == "client" ]]; then + files=( + ${ARCHIVE_FILES_SHARED[@]} + ${ARCHIVE_FILES_CLIENT[@]} + ) + elif [[ "$side" == "server" ]]; then + files=( + ${ARCHIVE_FILES_SHARED[@]} + ${ARCHIVE_FILES_SERVER[@]} + ) + else + echo "Invalid side: $side" + exit 1 + fi + + echo "Creating patch_${platform}_${side}.zip" + zip \ + --must-match \ + -qr \ + "${archives_dir}/${ARCHIVE_BASE_NAME}_patch_${platform}_${side}.zip" \ + "${files[@]}" + + echo "Creating patch_${platform}_${side}.tar.gz" + tar \ + -zcf "${archives_dir}/${ARCHIVE_BASE_NAME}_patch_${platform}_${side}.tar.gz" \ + --owner=0 --group=0 \ + "${files[@]}" + ) + done + + - name: Publish release + env: + CI_RELEASE_TOKEN: ${{ secrets.CI_RELEASE_TOKEN }} + run: | + set -e + tag="${{ inputs.tag }}" + target="${{ inputs.target }}" + prerelease=${{ inputs.prerelease || false }} + + api_url="${GITEA_API_URL:-https://git.illegalfiles.icu/api/v1}" + repo="${GITEA_REPOSITORY:-vlad.os/LuaCsForBarotraumaEP}" + + release_data=$(jq -n \ + --arg tag "$tag" \ + --arg target "$target" \ + --arg title "Automatic build" \ + --arg body "Automatic build" \ + --argjson prerelease $prerelease \ + '{tag_name: $tag, target_commitish: $target, name: $title, body: $body, prerelease: $prerelease}') + + release=$(curl -s -X POST \ + -H "Authorization: token $CI_RELEASE_TOKEN" \ + -H "Content-Type: application/json" \ + -d "$release_data" \ + "$api_url/repos/$repo/releases") + + release_id=$(echo "$release" | jq -r '.id') + if [[ "$release_id" == "null" ]]; then + echo "Failed to create release: $(echo "$release" | jq -r '.message')" + exit 1 + fi + + archives_dir="$(realpath -m "$CI_DIR/archives")" + for file in "$archives_dir"/*; do + if [[ -f "$file" ]]; then + echo "Uploading $(basename "$file")" + curl -s -X POST \ + -H "Authorization: token $CI_RELEASE_TOKEN" \ + -F "attachment=@$file" \ + "$api_url/repos/$repo/releases/$release_id/assets" + fi + done diff --git a/.gitea/workflows/run-tests.yml b/.gitea/workflows/run-tests.yml new file mode 100644 index 000000000..396fb6191 --- /dev/null +++ b/.gitea/workflows/run-tests.yml @@ -0,0 +1,44 @@ +name: Run tests + +on: + workflow_call: + inputs: + target: + required: true + type: string + +jobs: + run-tests: + runs-on: ubuntu-22.04 + steps: + - name: Checkout branch + uses: actions/checkout@v4 + with: + ref: ${{ inputs.target }} + submodules: recursive + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: | + 8.0.x + + - name: Initialize environment + run: | + mkdir -p ~/".local/share/Daedalic Entertainment GmbH/Barotrauma" + + - name: Run tests + continue-on-error: true + run: | + set +e + dotnet test LinuxSolution.sln -clp:"ErrorsOnly;Summary" --logger "trx;LogFileName=$PWD/test-results.trx" + echo "EXITCODE=$?" >> "$GITHUB_ENV" + + - name: Upload test results + uses: actions/upload-artifact@v4 + with: + name: test-results + path: test-results.trx + + - name: Set exit code + run: exit "$EXITCODE" diff --git a/.gitea/workflows/update-moonsharp.yml b/.gitea/workflows/update-moonsharp.yml new file mode 100644 index 000000000..c71cbbcd0 --- /dev/null +++ b/.gitea/workflows/update-moonsharp.yml @@ -0,0 +1,31 @@ +name: Update MoonSharp + +on: + workflow_dispatch: + +env: + SUBMODULE_PATH: Libraries/moonsharp + GIT_USER_EMAIL: "gitea-actions@git.illegalfiles.icu" + GIT_USER_NAME: "gitea-actions" + +jobs: + update-moonsharp: + runs-on: ubuntu-22.04 + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Update submodule + run: git submodule update --recursive --remote "$SUBMODULE_PATH" + + - name: Create commit + run: | + git config user.name "$GIT_USER_NAME" + git config user.email "$GIT_USER_EMAIL" + git commit -am "Update submodule: $SUBMODULE_PATH" + + - name: Push + run: git push diff --git a/README.md b/README.md index 4216a9c6b..d7342466d 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,14 @@ If you're interested in working on the code, either to develop mods or to contri **Wiki:** https://barotraumagame.com/wiki/Main_Page +## CI/CD Secrets + +The following secrets must be configured in the Gitea repository settings (`Settings → Secrets → Actions`): + +| Secret | Description | +|--------|-------------| +| `CI_RELEASE_TOKEN` | Gitea access token with `repo` scope for creating releases and reading repository info | + ## Prerequisities: ### Windows - [Visual Studio](https://www.visualstudio.com/vs/community/) with C# 10 support (VS 2022 or later recommended) @@ -90,6 +98,14 @@ If you're interested in working on the code, either to develop mods or to contri **Wiki:** https://barotraumagame.com/wiki/Main_Page +## CI/CD 密钥 + +以下密钥需在 Gitea 仓库设置中配置(`Settings → Secrets → Actions`): + +| 密钥 | 说明 | +|------|------| +| `CI_RELEASE_TOKEN` | 具有 `repo` 权限的 Gitea 访问令牌,用于创建发布版本和读取仓库信息 | + ## 环境要求: ### Windows - 支持 C# 10 的 [Visual Studio](https://www.visualstudio.com/vs/community/)(推荐 VS 2022 或更高版本)