From 1aad67fbc328845595c8b6f74bcde2000efce145 Mon Sep 17 00:00:00 2001 From: nerpa Date: Sat, 5 Sep 2026 12:18:59 +0300 Subject: [PATCH] ci: add gitea workflow tuned ci/cd - Use local actions mirrors. - Use actions/gitea-release-action@v1 instead of svenstaro/upload-release-action@v2. - Refactor code for fmt tests. - Disable go tests, use upstream as source of truth. --- .gitea/workflows/docker.yml | 157 +++++++++++ .gitea/workflows/release-win7.yml | 182 ++++++++++++ .gitea/workflows/release.yml | 279 +++++++++++++++++++ .gitea/workflows/scheduled-assets-update.yml | 136 +++++++++ .gitea/workflows/test.yml | 99 +++++++ infra/conf/xray.go | 2 +- 6 files changed, 854 insertions(+), 1 deletion(-) create mode 100644 .gitea/workflows/docker.yml create mode 100644 .gitea/workflows/release-win7.yml create mode 100644 .gitea/workflows/release.yml create mode 100644 .gitea/workflows/scheduled-assets-update.yml create mode 100644 .gitea/workflows/test.yml diff --git a/.gitea/workflows/docker.yml b/.gitea/workflows/docker.yml new file mode 100644 index 00000000..acbf7834 --- /dev/null +++ b/.gitea/workflows/docker.yml @@ -0,0 +1,157 @@ +name: Build and Push Docker Image + +on: + release: + types: + - published + - released + + workflow_dispatch: + inputs: + tag: + description: "Docker image tag:" + required: true + latest: + description: "Set to latest" + type: boolean + default: false + +jobs: + build-and-push: + if: (github.event.action != 'published') || (github.event.action == 'published' && github.event.release.prerelease == true) + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Set repository and image name to lowercase + env: + IMAGE_NAME: "${{ github.repository }}" + run: | + echo "IMAGE_NAME=${IMAGE_NAME,,}" >>${GITHUB_ENV} + echo "FULL_IMAGE_NAME=192.168.1.33/${IMAGE_NAME,,}" >>${GITHUB_ENV} + + - name: Validate and extract tag + run: | + SOURCE_TAG="${{ github.event.inputs.tag }}" + if [[ -z "$SOURCE_TAG" ]]; then + SOURCE_TAG="${{ github.ref_name }}" + fi + if [[ -z "$SOURCE_TAG" ]]; then + SOURCE_TAG="${{ github.event.release.tag_name }}" + fi + + if [[ -z "$SOURCE_TAG" ]]; then + echo "Error: Could not determine a valid tag source. Input tag and context tag (github.ref_name) are both empty." + exit 1 + fi + + if [[ "$SOURCE_TAG" =~ ^v[0-9]+\.[0-9] ]]; then + IMAGE_TAG="${SOURCE_TAG#v}" + else + IMAGE_TAG="$SOURCE_TAG" + fi + + echo "Docker image tag: '$IMAGE_TAG'." + echo "IMAGE_TAG=$IMAGE_TAG" >>${GITHUB_ENV} + + LATEST=false + if [[ "${{ github.event_name }}" == "release" && "${{ github.event.release.prerelease }}" == "false" ]] || [[ "${{ github.event_name }}" == "workflow_dispatch" && "${{ github.event.inputs.latest }}" == "true" ]]; then + LATEST=true + fi + + echo "Latest: '$LATEST'." + echo "LATEST=$LATEST" >>${GITHUB_ENV} + + NEWEST=false + if [[ "${{ github.event_name }}" == "release" ]]; then + NEWEST=true + fi + + echo "Newest: '$NEWEST'." + echo "NEWEST=$NEWEST" >>${GITHUB_ENV} + + - name: Checkout code + uses: actions/checkout@v7 + + - name: Fetch registry TLS certificate + run: | + mkdir -p "$RUNNER_TEMP/certs" + for host in 192.168.1.33 192.168.1.90; do + openssl s_client -connect "$host:443" -servername "$host" /dev/null \ + | openssl x509 -outform PEM > "$RUNNER_TEMP/certs/$host.crt" + done + cat "$RUNNER_TEMP/certs/"*.crt + + - name: Build custom buildkit image with trusted CA + run: | + cat > "$RUNNER_TEMP/Dockerfile.buildkit" <<'EOF' + FROM moby/buildkit:buildx-stable-1 + COPY certs/*.crt /usr/local/share/ca-certificates/ + RUN cat /usr/local/share/ca-certificates/*.crt >> /etc/ssl/certs/ca-certificates.crt + EOF + docker build -t local/buildkit-with-ca:latest \ + -f "$RUNNER_TEMP/Dockerfile.buildkit" "$RUNNER_TEMP" + + - name: Set up QEMU + uses: actions/setup-qemu-action@v4 + + - name: Set up Docker Buildx + uses: actions/setup-buildx-action@v3 + with: + driver: docker-container + driver-opts: | + image=local/buildkit-with-ca:latest + + - name: Login to GitHub Container Registry + uses: actions/login-action@v4 + with: + registry: 192.168.1.33/gitea + username: ${{ secrets.OCI_OWNER }} + password: ${{ secrets.OCI_TOKEN }} + + - name: Build Docker image (main architectures) + id: build_main_arches + uses: actions/build-push-action@v7 + with: + context: . + file: .github/docker/Dockerfile + platforms: | + linux/amd64 + linux/arm64/v8 + provenance: false + outputs: type=image,name=${{ env.FULL_IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true + + - name: Create manifest list and push + run: | + echo "Creating multi-arch manifest with tag: '${{ env.FULL_IMAGE_NAME }}:${{ env.IMAGE_TAG }}'." + docker buildx imagetools create \ + --tag ${{ env.FULL_IMAGE_NAME }}:${{ env.IMAGE_TAG }} \ + ${{ env.FULL_IMAGE_NAME }}@${{ steps.build_main_arches.outputs.digest }} + + if [[ "${{ env.LATEST }}" == "true" ]]; then + echo "Adding 'latest' tag to manifest: '${{ env.FULL_IMAGE_NAME }}:latest'." + docker buildx imagetools create \ + --tag ${{ env.FULL_IMAGE_NAME }}:latest \ + ${{ env.FULL_IMAGE_NAME }}:${{ env.IMAGE_TAG }} + fi + + if [[ "${{ env.NEWEST }}" == "true" ]]; then + echo "Adding 'pre-release' tag to manifest: '${{ env.FULL_IMAGE_NAME }}:pre-release'." + docker buildx imagetools create \ + --tag ${{ env.FULL_IMAGE_NAME }}:pre-release \ + ${{ env.FULL_IMAGE_NAME }}:${{ env.IMAGE_TAG }} + fi + + - name: Inspect image + run: | + docker buildx imagetools inspect ${{ env.FULL_IMAGE_NAME }}:${{ env.IMAGE_TAG }} + + if [[ "${{ env.LATEST }}" == "true" ]]; then + docker buildx imagetools inspect ${{ env.FULL_IMAGE_NAME }}:latest + fi + + if [[ "${{ env.NEWEST }}" == "true" ]]; then + docker buildx imagetools inspect ${{ env.FULL_IMAGE_NAME }}:pre-release + fi diff --git a/.gitea/workflows/release-win7.yml b/.gitea/workflows/release-win7.yml new file mode 100644 index 00000000..d6349ca6 --- /dev/null +++ b/.gitea/workflows/release-win7.yml @@ -0,0 +1,182 @@ +name: Build and Release for Windows 7 + +on: + workflow_dispatch: + release: + types: [published] + push: + pull_request: + types: [opened, synchronize, reopened] + +jobs: + check-assets: + runs-on: ubuntu-latest + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name + steps: + - name: Restore Geodat Cache + uses: actions/cache/restore@v6 + with: + path: resources + key: xray-geodat- + + - name: Restore Wintun Cache + uses: actions/cache/restore@v6 + with: + path: resources + key: xray-wintun- + + - name: Check Assets Existence + id: check-assets + run: | + [ -d 'resources' ] || mkdir resources + LIST=('geoip.dat' 'geosite.dat') + for FILE_NAME in "${LIST[@]}" + do + echo -e "Checking ${FILE_NAME}..." + if [ -s "./resources/${FILE_NAME}" ]; then + echo -e "${FILE_NAME} exists." + else + echo -e "${FILE_NAME} does not exist." + echo "missing=true" >> $GITHUB_OUTPUT + break + fi + done + LIST=('amd64' 'x86') + for ARCHITECTURE in "${LIST[@]}" + do + echo -e "Checking wintun.dll for ${ARCHITECTURE}..." + if [ -s "./resources/wintun/bin/${ARCHITECTURE}/wintun.dll" ]; then + echo -e "wintun.dll for ${ARCHITECTURE} exists." + else + echo -e "wintun.dll for ${ARCHITECTURE} is missing." + echo "missing=true" >> $GITHUB_OUTPUT + break + fi + done + + - name: Sleep for 90 seconds if Assets Missing + if: steps.check-assets.outputs.missing == 'true' + run: sleep 90 + + build: + needs: check-assets + permissions: + contents: write + strategy: + matrix: + include: + # BEGIN Windows 7 + - goos: windows + goarch: amd64 + assetname: win7-64 + # - goos: windows + # goarch: 386 + # assetname: win7-32 + # END Windows 7 + fail-fast: false + + runs-on: ubuntu-latest + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name + env: + GOOS: ${{ matrix.goos}} + GOARCH: ${{ matrix.goarch }} + CGO_ENABLED: 0 + steps: + - name: Checkout codebase + uses: actions/checkout@v7 + + - name: Show workflow information + run: | + _NAME=${{ matrix.assetname }} + echo "GOOS: ${{ matrix.goos }}, GOARCH: ${{ matrix.goarch }}, RELEASE_NAME: $_NAME" + echo "ASSET_NAME=$_NAME" >> $GITHUB_ENV + + - name: Set up Go + uses: actions/setup-go@v7 + with: + go-version-file: go.mod + check-latest: true + + - name: Setup patched builder + run: | + GOSDK=$(go env GOROOT) + rm -r $GOSDK/* + cd $GOSDK + curl -O -L -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" https://github.com/XTLS/go-win7/releases/latest/download/go-for-win7-linux-amd64.zip + unzip ./go-for-win7-linux-amd64.zip -d $GOSDK + rm ./go-for-win7-linux-amd64.zip + + - name: Get project dependencies + run: go mod download + + - name: Build Xray + run: | + mkdir -p build_assets + COMMID=$(git describe --always --dirty) + echo 'Building Xray for Windows 7...' + go build -o build_assets/xray.exe -trimpath -buildvcs=false -gcflags="all=-l=4" -ldflags="-X github.com/xtls/xray-core/core.build=${COMMID} -s -w -buildid=" -v ./main + # The line below is for without running conhost.exe version. Commented for not being used. Provided for reference. + # go build -o build_assets/wxray.exe -trimpath -buildvcs=false -gcflags="all=-l=4" -ldflags="-H windowsgui -X github.com/xtls/xray-core/core.build=${COMMID} -s -w -buildid=" -v ./main + + - name: Restore Geodat Cache + uses: actions/cache/restore@v6 + with: + path: resources + key: xray-geodat- + + - name: Restore Wintun Cache + uses: actions/cache/restore@v6 + with: + path: resources + key: xray-wintun- + + - name: Add additional assets into package + run: | + mv -f resources/geo* build_assets/ + if [[ ${GOOS} == 'windows' ]]; then + cp .github/build/windows/* build_assets/ + fi + if [[ ${GOOS} == 'windows' ]]; then + echo 'Adding Wintun into packages' + if [[ ${GOARCH} == 'amd64' ]]; then + mv resources/wintun/bin/amd64/wintun.dll build_assets/ + fi + if [[ ${GOARCH} == '386' ]]; then + mv resources/wintun/bin/x86/wintun.dll build_assets/ + fi + mv resources/wintun/LICENSE.txt build_assets/LICENSE-Wintun + fi + + - name: Copy README.md & LICENSE + run: | + cp ${GITHUB_WORKSPACE}/README.md ./build_assets/README.md + cp ${GITHUB_WORKSPACE}/LICENSE ./build_assets/LICENSE + + - name: Create ZIP archive + if: github.event_name == 'release' + shell: bash + run: | + pushd build_assets || exit 1 + touch -mt $(date +%Y01010000) * + zip -9vr ../Xray-${{ env.ASSET_NAME }}.zip . + popd || exit 1 + FILE=./Xray-${{ env.ASSET_NAME }}.zip + DGST=$FILE.dgst + for METHOD in {"md5","sha1","sha256","sha512"} + do + openssl dgst -$METHOD $FILE | sed 's/([^)]*)//g' >>$DGST + done + + - name: Upload binaries to release + uses: actions/gitea-release-action@v1 + if: github.event_name == 'release' + with: + files: ./Xray-${{ env.ASSET_NAME }}.zip* + tag_name: ${{ github.ref_name }} + + - name: Upload files to Artifacts + uses: actions/upload-artifact@v7 + with: + name: Xray-${{ env.ASSET_NAME }} + path: | + ./build_assets/* diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml new file mode 100644 index 00000000..97adfbfc --- /dev/null +++ b/.gitea/workflows/release.yml @@ -0,0 +1,279 @@ +name: Build and Release + +on: + workflow_dispatch: + release: + types: [published] + push: + pull_request: + types: [opened, synchronize, reopened] + +jobs: + check-assets: + runs-on: ubuntu-latest + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name + steps: + - name: Restore Geodat Cache + uses: actions/cache/restore@v6 + with: + path: resources + key: xray-geodat- + + - name: Restore Wintun Cache + uses: actions/cache/restore@v6 + with: + path: resources + key: xray-wintun- + + - name: Check Assets Existence + id: check-assets + run: | + [ -d 'resources' ] || mkdir resources + LIST=('geoip.dat' 'geosite.dat') + for FILE_NAME in "${LIST[@]}" + do + echo -e "Checking ${FILE_NAME}..." + if [ -s "./resources/${FILE_NAME}" ]; then + echo -e "${FILE_NAME} exists." + else + echo -e "${FILE_NAME} does not exist." + echo "missing=true" >> $GITHUB_OUTPUT + break + fi + done + LIST=('amd64' 'x86' 'arm64') + for ARCHITECTURE in "${LIST[@]}" + do + echo -e "Checking wintun.dll for ${ARCHITECTURE}..." + if [ -s "./resources/wintun/bin/${ARCHITECTURE}/wintun.dll" ]; then + echo -e "wintun.dll for ${ARCHITECTURE} exists." + else + echo -e "wintun.dll for ${ARCHITECTURE} is missing." + echo "missing=true" >> $GITHUB_OUTPUT + break + fi + done + + - name: Trigger Asset Update Workflow if Assets Missing + if: steps.check-assets.outputs.missing == 'true' + uses: actions/github-script@v9 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const { owner, repo } = context.repo; + await github.rest.actions.createWorkflowDispatch({ + owner, + repo, + workflow_id: 'scheduled-assets-update.yml', + ref: context.ref + }); + console.log('Triggered scheduled-assets-update.yml due to missing assets on branch:', context.ref); + + - name: Sleep for 90 seconds if Assets Missing + if: steps.check-assets.outputs.missing == 'true' + run: sleep 90 + + build: + needs: check-assets + permissions: + contents: write + strategy: + matrix: + # Include amd64 on all platforms. + goos: [linux] + goarch: [amd64] + patch-assetname: [""] + exclude: + # Exclude i386 on darwin + - goarch: 386 + goos: darwin + include: + # BEGIN MacOS ARM64 + # - goos: darwin + # goarch: arm64 + # END MacOS ARM64 + # BEGIN Linux ARM 5 6 7 + # - goos: linux + # goarch: arm + # goarm: 7 + # - goos: linux + # goarch: arm + # goarm: 6 + # - goos: linux + # goarch: arm + # goarm: 5 + # END Linux ARM 5 6 7 + # BEGIN Android ARM 8 + # - goos: android + # goarch: arm64 + # END Android ARM 8 + # BEGIN Android AMD64 + # - goos: android + # goarch: amd64 + # patch-assetname: android-amd64 + # END Android AMD64 + # Windows ARM + # - goos: windows + # goarch: arm64 + # BEGIN Other architectures + # BEGIN riscv64 & ARM64 & LOONG64 + - goos: linux + goarch: arm64 + # - goos: linux + # goarch: riscv64 + # - goos: linux + # goarch: loong64 + # END riscv64 & ARM64 & LOONG64 + # BEGIN MIPS + # - goos: linux + # goarch: mips64 + # - goos: linux + # goarch: mips64le + # - goos: linux + # goarch: mipsle + # - goos: linux + # goarch: mips + # END MIPS + # BEGIN PPC + # - goos: linux + # goarch: ppc64 + # - goos: linux + # goarch: ppc64le + # END PPC + # BEGIN FreeBSD ARM + # - goos: freebsd + # goarch: arm64 + # - goos: freebsd + # goarch: arm + # goarm: 7 + # END FreeBSD ARM + # BEGIN S390X + # - goos: linux + # goarch: s390x + # END S390X + # END Other architectures + # BEGIN OPENBSD ARM + # - goos: openbsd + # goarch: arm64 + # - goos: openbsd + # goarch: arm + # goarm: 7 + # END OPENBSD ARM + fail-fast: false + + runs-on: ubuntu-latest + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name + env: + GOOS: ${{ matrix.goos }} + GOARCH: ${{ matrix.goarch }} + GOARM: ${{ matrix.goarm }} + CGO_ENABLED: 0 + steps: + - name: Checkout codebase + uses: actions/checkout@v7 + + - name: Show workflow information + run: | + _NAME=${{ matrix.patch-assetname }} + [ -n "$_NAME" ] || _NAME=$(jq ".[\"$GOOS-$GOARCH$GOARM$GOMIPS\"].friendlyName" -r < .github/build/friendly-filenames.json) + echo "GOOS: $GOOS, GOARCH: $GOARCH, GOARM: $GOARM, GOMIPS: $GOMIPS, RELEASE_NAME: $_NAME" + echo "ASSET_NAME=$_NAME" >> $GITHUB_ENV + + - name: Set up Go + uses: actions/setup-go@v7 + with: + go-version-file: go.mod + check-latest: true + + - name: Get project dependencies + run: go mod download + + - name: Build Xray + run: | + mkdir -p build_assets + COMMID=$(git describe --always --dirty) + if [[ ${GOOS} == 'windows' ]]; then + echo 'Building Xray for Windows...' + go build -o build_assets/xray.exe -trimpath -buildvcs=false -gcflags="all=-l=4" -ldflags="-X github.com/xtls/xray-core/core.build=${COMMID} -s -w -buildid=" -v ./main + # The line below is for without running conhost.exe version. Commented for not being used. Provided for reference. + # go build -o build_assets/wxray.exe -trimpath -buildvcs=false -gcflags="all=-l=4" -ldflags="-H windowsgui -X github.com/xtls/xray-core/core.build=${COMMID} -s -w -buildid=" -v ./main + elif [[ ${GOOS} == 'android' ]]; then + echo 'Building Xray for Android...' + go build -o build_assets/xray -trimpath -buildvcs=false -gcflags="all=-l=4" -ldflags="-X github.com/xtls/xray-core/core.build=${COMMID} -s -w -buildid= -checklinkname=0" -v ./main + else + echo 'Building Xray...' + if [[ ${GOARCH} == 'mips' || ${GOARCH} == 'mipsle' ]]; then + go build -o build_assets/xray -trimpath -buildvcs=false -gcflags="-l=4" -ldflags="-X github.com/xtls/xray-core/core.build=${COMMID} -s -w -buildid=" -v ./main + echo 'Building soft-float Xray for MIPS/MIPSLE 32-bit...' + GOMIPS=softfloat go build -o build_assets/xray_softfloat -trimpath -buildvcs=false -gcflags="-l=4" -ldflags="-X github.com/xtls/xray-core/core.build=${COMMID} -s -w -buildid=" -v ./main + else + go build -o build_assets/xray -trimpath -buildvcs=false -gcflags="all=-l=4" -ldflags="-X github.com/xtls/xray-core/core.build=${COMMID} -s -w -buildid=" -v ./main + fi + fi + + - name: Restore Geodat Cache + uses: actions/cache/restore@v6 + with: + path: resources + key: xray-geodat- + + - name: Restore Wintun Cache + if: matrix.goos == 'windows' + uses: actions/cache/restore@v6 + with: + path: resources + key: xray-wintun- + + - name: Add additional assets into package + run: | + mv -f resources/geo* build_assets/ + if [[ ${GOOS} == 'windows' ]]; then + cp .github/build/windows/* build_assets/ + fi + if [[ ${GOOS} == 'windows' ]]; then + echo 'Adding Wintun into packages' + if [[ ${GOARCH} == 'amd64' ]]; then + mv resources/wintun/bin/amd64/wintun.dll build_assets/ + fi + if [[ ${GOARCH} == '386' ]]; then + mv resources/wintun/bin/x86/wintun.dll build_assets/ + fi + if [[ ${GOARCH} == 'arm64' ]]; then + mv resources/wintun/bin/arm64/wintun.dll build_assets/ + fi + mv resources/wintun/LICENSE.txt build_assets/LICENSE-Wintun + fi + + - name: Copy README.md & LICENSE + run: | + cp ${GITHUB_WORKSPACE}/README.md ./build_assets/README.md + cp ${GITHUB_WORKSPACE}/LICENSE ./build_assets/LICENSE + + - name: Create ZIP archive + if: github.event_name == 'release' + shell: bash + run: | + pushd build_assets || exit 1 + touch -mt $(date +%Y01010000) * + zip -9vr ../Xray-${{ env.ASSET_NAME }}.zip . + popd || exit 1 + FILE=./Xray-${{ env.ASSET_NAME }}.zip + DGST=$FILE.dgst + for METHOD in {"md5","sha1","sha256","sha512"} + do + openssl dgst -$METHOD $FILE | sed 's/([^)]*)//g' >>$DGST + done + + - name: Upload binaries to release + uses: actions/gitea-release-action@v1 + if: github.event_name == 'release' + with: + files: ./Xray-${{ env.ASSET_NAME }}.zip* + tag_name: ${{ github.ref_name }} + + - name: Upload files to Artifacts + uses: actions/upload-artifact@v7 + with: + name: Xray-${{ env.ASSET_NAME }} + path: | + ./build_assets/* diff --git a/.gitea/workflows/scheduled-assets-update.yml b/.gitea/workflows/scheduled-assets-update.yml new file mode 100644 index 00000000..434f9340 --- /dev/null +++ b/.gitea/workflows/scheduled-assets-update.yml @@ -0,0 +1,136 @@ +name: Scheduled assets update + +# NOTE: This Github Actions is required by other actions, for preparing other packaging assets in a +# routine manner, for example: GeoIP/GeoSite. +# Currently updating: +# - Geodat (GeoIP/Geosite) +# - Wintun (wintun.dll) + +on: + workflow_dispatch: + schedule: + # Update GeoData on every day (22:30 UTC) + - cron: "30 22 * * *" + push: + # Prevent triggering update request storm + paths: + - ".github/workflows/scheduled-assets-update.yml" + pull_request: + # Prevent triggering update request storm + paths: + - ".github/workflows/scheduled-assets-update.yml" + +jobs: + geodat: + if: github.event.schedule == '30 22 * * *' || github.event_name == 'push' || github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch' + runs-on: ubuntu-latest + steps: + - name: Restore Geodat Cache + uses: actions/cache/restore@v6 + with: + path: resources + key: xray-geodat- + + - name: Update Geodat + id: update + uses: actions/nick-fields-retry@v4 + with: + timeout_minutes: 60 + retry_wait_seconds: 60 + max_attempts: 60 + command: | + [ -d 'resources' ] || mkdir resources + LIST=('Loyalsoldier v2ray-rules-dat geoip geoip' 'Loyalsoldier v2ray-rules-dat geosite geosite') + for i in "${LIST[@]}" + do + INFO=($(echo $i | awk 'BEGIN{FS=" ";OFS=" "} {print $1,$2,$3,$4}')) + FILE_NAME="${INFO[3]}.dat" + echo -e "Verifying HASH key..." + HASH="$(curl -sL "https://raw.githubusercontent.com/${INFO[0]}/${INFO[1]}/release/${INFO[2]}.dat.sha256sum" | awk -F ' ' '{print $1}')" + if [ -s "./resources/${FILE_NAME}" ] && [ "$(sha256sum "./resources/${FILE_NAME}" | awk -F ' ' '{print $1}')" == "${HASH}" ]; then + continue + else + echo -e "Downloading https://raw.githubusercontent.com/${INFO[0]}/${INFO[1]}/release/${INFO[2]}.dat..." + curl -L "https://raw.githubusercontent.com/${INFO[0]}/${INFO[1]}/release/${INFO[2]}.dat" -o ./resources/${FILE_NAME} + echo -e "Verifying HASH key..." + [ "$(sha256sum "./resources/${FILE_NAME}" | awk -F ' ' '{print $1}')" == "${HASH}" ] || { echo -e "The HASH key of ${FILE_NAME} does not match cloud one."; exit 1; } + echo "unhit=true" >> $GITHUB_OUTPUT + fi + done + + - name: Save Geodat Cache + uses: actions/cache/save@v6 + if: ${{ steps.update.outputs.unhit }} + with: + path: resources + key: xray-geodat-${{ github.sha }}-${{ github.run_number }} + + wintun: + if: github.event.schedule == '30 22 * * *' || github.event_name == 'push' || github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch' + runs-on: ubuntu-latest + env: + ASSETVER: 0.14.1 + ASSETHASH: 07c256185d6ee3652e09fa55c0b673e2624b565e02c4b9091c79ca7d2f24ef51 + steps: + - name: Restore Wintun Cache + uses: actions/cache/restore@v6 + with: + path: resources + key: xray-wintun- + + - name: Force downloading if run manually or on file update + if: github.event_name == 'workflow_dispatch' || github.event_name == 'push' + run: | + echo "FORCE_UPDATE=true" >> $GITHUB_ENV + + - name: Update Wintun + id: update + uses: actions/nick-fields-retry@v4 + with: + timeout_minutes: 60 + retry_wait_seconds: 60 + max_attempts: 60 + command: | + [ -d 'resources' ] || mkdir resources + LIST=('amd64' 'x86' 'arm64') + for ARCHITECTURE in "${LIST[@]}" + do + FILE_PATH="resources/wintun/bin/${ARCHITECTURE}/wintun.dll" + echo -e "Checking if wintun.dll for ${ARCHITECTURE} exists..." + if [ -s "./resources/wintun/bin/${ARCHITECTURE}/wintun.dll" ]; then + echo -e "wintun.dll for ${ARCHITECTURE} exists" + else + echo -e "wintun.dll for ${ARCHITECTURE} is missing" + missing=true + fi + done + if [ -s "./resources/wintun/LICENSE.txt" ]; then + echo -e "LICENSE for Wintun exists" + else + echo -e "LICENSE for Wintun is missing" + missing=true + fi + if [[ -v FORCE_UPDATE ]]; then + missing=true + fi + if [[ "$missing" == true ]]; then + FILENAME=wintun.zip + DOWNLOAD_FILE=wintun-${ASSETVER}.zip + echo -e "Downloading https://www.wintun.net/builds/${DOWNLOAD_FILE}..." + curl -L "https://www.wintun.net/builds/${DOWNLOAD_FILE}" -o "${FILENAME}" + if [[ "$(sha256sum "./${FILENAME}" | awk -F ' ' '{print $1}')" == "${ASSETHASH}" ]]; then + echo -e "Unpacking wintun..." + unzip -u ${FILENAME} -d resources/ + echo "unhit=true" >> $GITHUB_OUTPUT + else + echo -e "Digest of ${FILENAME} mismatch." + exit 1 + fi + fi + + - name: Save Wintun Cache + uses: actions/cache/save@v6 + if: ${{ steps.update.outputs.unhit }} + with: + path: resources + key: xray-wintun-${{ github.sha }}-${{ github.run_number }} diff --git a/.gitea/workflows/test.yml b/.gitea/workflows/test.yml new file mode 100644 index 00000000..5307863a --- /dev/null +++ b/.gitea/workflows/test.yml @@ -0,0 +1,99 @@ +name: Tests and Checkings + +on: + push: + pull_request: + types: [opened, synchronize, reopened] + +jobs: + check-assets: + runs-on: ubuntu-latest + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name + steps: + - name: Restore Geodat Cache + uses: actions/cache/restore@v6 + with: + path: resources + key: xray-geodat- + - name: Check Assets Existence + id: check-assets + run: | + [ -d 'resources' ] || mkdir resources + LIST=('geoip.dat' 'geosite.dat') + for FILE_NAME in "${LIST[@]}" + do + echo -e "Checking ${FILE_NAME}..." + if [ -s "./resources/${FILE_NAME}" ]; then + echo -e "${FILE_NAME} exists." + else + echo -e "${FILE_NAME} does not exist." + echo "missing=true" >> $GITHUB_OUTPUT + break + fi + done + - name: Sleep for 90 seconds if Assets Missing + if: steps.check-assets.outputs.missing == 'true' + run: sleep 90 + + check-proto: + runs-on: ubuntu-latest + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name + steps: + - name: Checkout codebase + uses: actions/checkout@v7 + - name: Check Proto Version Header + run: | + head -n 4 core/config.pb.go > ref.txt + find . -name "*.pb.go" ! -name "*_grpc.pb.go" -print0 | while IFS= read -r -d '' file; do + if ! cmp -s ref.txt <(head -n 4 "$file"); then + echo "Error: Header mismatch in $file" + head -n 4 "$file" + exit 1 + fi + done + + check-format: + runs-on: ubuntu-latest + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name + permissions: + contents: read + steps: + - name: Checkout codebase + uses: actions/checkout@v7 + - name: Set up Go + uses: actions/setup-go@v7 + with: + go-version-file: go.mod + check-latest: true + cache: false + - name: Check Format + run: | + go install -v mvdan.cc/gofumpt@latest + go run ./infra/vformat/main.go -mode check -pwd ./ + + # test: + # needs: check-assets + # if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name + # permissions: + # contents: read + # runs-on: ${{ matrix.os }} + # strategy: + # fail-fast: false + # matrix: + # os: [ubuntu-latest] + # steps: + # - name: Checkout codebase + # uses: actions/checkout@v7 + # - name: Set up Go + # uses: actions/setup-go@v7 + # with: + # go-version-file: go.mod + # check-latest: true + # - name: Restore Geodat Cache + # uses: actions/cache/restore@v6 + # with: + # path: resources + # key: xray-geodat- + # enableCrossOsArchive: true + # - name: Test + # run: go test -timeout 1h -v ./... diff --git a/infra/conf/xray.go b/infra/conf/xray.go index 894a6998..6e60c27a 100644 --- a/infra/conf/xray.go +++ b/infra/conf/xray.go @@ -50,7 +50,7 @@ var ( "hysteria": func() interface{} { return new(HysteriaClientConfig) }, "dns": func() interface{} { return new(DNSOutboundConfig) }, "wireguard": func() interface{} { return &WireGuardConfig{IsClient: true} }, - "amnezia": func() interface{} { return &AmneziaConfig{IsClient: true} }, + "amnezia": func() interface{} { return &AmneziaConfig{IsClient: true} }, }, "protocol", "settings") )