name: Release # Gitea Actions workflow: # - pushes to main build the Windows GNU package and publish a build-date Release. # - tag pushes (v*) build the Windows GNU package and publish the matching Release. # - manual runs build the same package and publish a build-date Release. on: push: branches: ["main"] tags: ["v*"] workflow_dispatch: permissions: contents: write jobs: build-windows-gnu: name: windows-x86_64-gnu runs-on: ubuntu-latest env: TARGET: x86_64-pc-windows-gnu BIN: meatshell.exe CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER: x86_64-w64-mingw32-gcc CARGO_TARGET_X86_64_PC_WINDOWS_GNU_AR: x86_64-w64-mingw32-ar CC_x86_64_pc_windows_gnu: x86_64-w64-mingw32-gcc CXX_x86_64_pc_windows_gnu: x86_64-w64-mingw32-g++ AR_x86_64_pc_windows_gnu: x86_64-w64-mingw32-ar WINDRES: x86_64-w64-mingw32-windres PKG_CONFIG_ALLOW_CROSS: "1" steps: - name: Free disk space run: | sudo rm -rf /usr/local/lib/android /usr/share/dotnet /opt/ghc || true sudo rm -rf /usr/local/graalvm /usr/local/share/powershell /usr/local/share/chromium || true sudo rm -rf /usr/local/lib/node_modules /usr/share/swift /usr/share/miniconda || true sudo docker image prune -af 2>/dev/null || true sudo apt-get clean || true sudo rm -rf /var/cache/apt/archives/* || true df -h - uses: actions/checkout@v4 with: clean: false - name: Install system dependencies run: | sudo dpkg --add-architecture i386 sudo apt-get update sudo apt-get install -y \ gcc-mingw-w64-x86-64 \ binutils-mingw-w64-x86-64 \ wine64 wine32 wine \ xvfb \ zip sudo apt-get clean sudo rm -rf /var/cache/apt/archives/* df -h - name: Cache Cargo registry uses: actions/cache@v4 with: path: | ~/.cargo/registry ~/.cargo/git key: ${{ runner.os }}-${{ env.TARGET }}-cargo-${{ hashFiles('Cargo.lock') }} restore-keys: | ${{ runner.os }}-${{ env.TARGET }}-cargo- ${{ runner.os }}-cargo- - name: Install Rust toolchain uses: dtolnay/rust-toolchain@stable with: targets: ${{ env.TARGET }} - name: Show toolchain run: | rustc --version cargo --version x86_64-w64-mingw32-gcc --version | head -n 1 - name: Clean partial cargo cache run: | rm -rf ~/.cargo/registry/src rm -rf ~/.cargo/registry/cache df -h - name: Fetch dependencies run: | for i in 1 2 3 4 5; do echo "Attempt $i to fetch dependencies..." if cargo fetch 2>&1; then echo "✅ Cargo fetch succeeded on attempt $i" break fi if [ $i -eq 5 ]; then echo "❌ Cargo fetch failed after 5 attempts" exit 1 fi echo "Waiting 10 seconds before retry..." sleep 10 done - name: Build Windows GNU release run: | cargo build --release --target "$TARGET" - name: Package Windows zip env: EVENT_NAME: ${{ gitea.event_name }} REF: ${{ gitea.ref }} REF_NAME: ${{ gitea.ref_name }} run: | set -eu BUILD_DIR="${CARGO_TARGET_DIR:-target}" event_name="${EVENT_NAME:-}" ref="${REF:-}" ref_name="${REF_NAME:-dev}" short_sha="$(git rev-parse --short=12 HEAD)" if [ "$event_name" = "push" ] && [ "$ref" = "refs/tags/${ref_name}" ]; then VERSION="${ref_name}-${short_sha}" RELEASE_TAG="${ref_name}" elif [ "$event_name" = "push" ] && [ "$ref" != "refs/heads/main" ]; then VERSION="${ref_name}-${short_sha}" RELEASE_TAG="${ref_name}" else BUILD_STAMP="$(date -u +%Y%m%d-%H%M%S)" VERSION="build-${BUILD_STAMP}-${short_sha}" RELEASE_TAG="$VERSION" fi RELEASE_NAME="$RELEASE_TAG" STAGE="meatshell-${VERSION}-windows-x86_64-gnu" mkdir -p "$STAGE" cp "${BUILD_DIR}/${TARGET}/release/${BIN}" "$STAGE/" cp README.md README.en.md CHANGELOG.md "$STAGE/" 2>/dev/null || true zip -r "${STAGE}.zip" "$STAGE" echo "ASSET=${STAGE}.zip" >> "$GITHUB_ENV" echo "RELEASE_TAG=${RELEASE_TAG}" >> "$GITHUB_ENV" echo "RELEASE_NAME=${RELEASE_NAME}" >> "$GITHUB_ENV" - name: Publish Gitea release if: startsWith(github.ref, 'refs/tags/') || github.ref == 'refs/heads/main' env: GITEA_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | set -eu TAG="${{ env.RELEASE_TAG }}" NAME="${{ env.RELEASE_NAME }}" FILE="${{ env.ASSET }}" # Try GITHUB_SERVER_URL first, fall back to GITEA_URL or localhost BASE_URL="${GITHUB_SERVER_URL:-${GITEA_URL:-http://localhost:3000}}" API="${BASE_URL}/api/v1" REPO="${GITHUB_REPOSITORY:-$(git remote get-url origin | sed 's#.*[:/]\([^/]*/[^/]*\)\.git#\1#')}" echo "Creating release ${TAG} on ${API}/repos/${REPO}..." RELEASE_ID=$(curl -s -w '%{http_code}' -X POST \ -H "Authorization: token ${GITEA_TOKEN}" \ -H "Content-Type: application/json" \ "${API}/repos/${REPO}/releases" \ -d "{\"tag_name\":\"${TAG}\",\"name\":\"${NAME}\",\"draft\":false,\"prerelease\":false}" \ -o /tmp/release.json | tail -c3) if [ "$RELEASE_ID" = "409" ]; then echo "Release ${TAG} already exists, updating..." curl -s -X PATCH \ -H "Authorization: token ${GITEA_TOKEN}" \ -H "Content-Type: application/json" \ "${API}/repos/${REPO}/releases/tags/${TAG}" \ -d "{\"name\":\"${NAME}\"}" > /dev/null fi ATTACH_URL="${API}/repos/${REPO}/releases/tags/${TAG}/assets" echo "Uploading ${FILE} to ${ATTACH_URL}..." curl -s -X POST \ -H "Authorization: token ${GITEA_TOKEN}" \ -H "Content-Type: application/zip" \ --data-binary "@${FILE}" \ "${ATTACH_URL}?filename=$(basename ${FILE})" echo "✅ Release ${TAG} published"