name: Build and Release on: push: branches: - main - release/* tags: - 'v*' pull_request: branches: - main env: GOPROXY: https://proxy.golang.org,direct GO_VERSION: "1.25" NODE_VERSION: "22" jobs: # Lint and test job lint-test: name: Lint and Test runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 0 - name: Check for existing Go id: go-check run: | if command -v go &> /dev/null; then GO_VER=$(go version | grep -oP 'go\d+\.\d+' | head -1) echo "version=$GO_VER" >> $GITHUB_OUTPUT echo "Found Go: $(go version)" fi - name: Setup Go if: steps.go-check.outputs.version == '' uses: actions/setup-go@v5 with: go-version: ${{ env.GO_VERSION }} cache: true - name: Check for existing Node.js id: node-check run: | if command -v node &> /dev/null; then NODE_VER=$(node --version) echo "version=$NODE_VER" >> $GITHUB_OUTPUT echo "Found Node.js: $NODE_VER" fi - name: Setup Node.js if: steps.node-check.outputs.version == '' uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} - name: Check for existing pnpm id: pnpm-check run: | if command -v pnpm &> /dev/null; then PNPM_VER=$(pnpm --version) echo "version=$PNPM_VER" >> $GITHUB_OUTPUT echo "Found pnpm: $PNPM_VER" fi - name: Install pnpm if: steps.pnpm-check.outputs.version == '' run: npm install -g pnpm - name: Install dependencies run: make deps-frontend deps-backend - name: Run linters run: make lint-go lint-frontend continue-on-error: true - name: Run tests run: make test continue-on-error: true env: GITEA_I_AM_BEING_UNSAFE_RUNNING_AS_ROOT: true # Build job for binaries build: name: Build Binaries runs-on: ubuntu-latest needs: lint-test strategy: matrix: include: - goos: linux goarch: amd64 - goos: linux goarch: arm64 - goos: darwin goarch: amd64 - goos: darwin goarch: arm64 - goos: windows goarch: amd64 steps: - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 0 - name: Check for existing Go id: go-check run: | if command -v go &> /dev/null; then GO_VER=$(go version | grep -oP 'go\d+\.\d+' | head -1) echo "version=$GO_VER" >> $GITHUB_OUTPUT echo "Found Go: $(go version)" fi - name: Setup Go if: steps.go-check.outputs.version == '' uses: actions/setup-go@v5 with: go-version: ${{ env.GO_VERSION }} cache: true - name: Check for existing Node.js id: node-check run: | if command -v node &> /dev/null; then NODE_VER=$(node --version) echo "version=$NODE_VER" >> $GITHUB_OUTPUT echo "Found Node.js: $NODE_VER" fi - name: Setup Node.js if: steps.node-check.outputs.version == '' uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} - name: Check for existing pnpm id: pnpm-check run: | if command -v pnpm &> /dev/null; then PNPM_VER=$(pnpm --version) echo "version=$PNPM_VER" >> $GITHUB_OUTPUT echo "Found pnpm: $PNPM_VER" fi - name: Install pnpm if: steps.pnpm-check.outputs.version == '' run: npm install -g pnpm - name: Install dependencies run: make deps-frontend deps-backend - name: Build frontend run: make frontend - name: Generate bindata run: make generate env: TAGS: bindata - name: Build binary env: GOOS: ${{ matrix.goos }} GOARCH: ${{ matrix.goarch }} TAGS: bindata sqlite sqlite_unlock_notify run: | VERSION=$(git describe --tags --always --dirty 2>/dev/null || echo "dev") LDFLAGS="-X code.gitea.io/gitea/modules/setting.AppVer=${VERSION}" EXT="" if [ "$GOOS" = "windows" ]; then EXT=".exe" fi OUTPUT="gitea-${VERSION}-${GOOS}-${GOARCH}${EXT}" go build -v -trimpath -tags "${TAGS}" -ldflags "${LDFLAGS}" -o "dist/${OUTPUT}" . # Create checksum cd dist && sha256sum "${OUTPUT}" > "${OUTPUT}.sha256" - name: Upload to release if: startsWith(github.ref, 'refs/tags/v') run: | VERSION=$(git describe --tags --always 2>/dev/null || echo "dev") echo "Uploading binaries for $VERSION" # Get or create release TAG="${{ github.ref_name }}" EXISTING=$(curl -s \ -H "Authorization: token ${{ secrets.RELEASE_TOKEN }}" \ "${{ github.server_url }}/api/v1/repos/${{ github.repository }}/releases/tags/$TAG") if echo "$EXISTING" | grep -q '"id":[0-9]'; then RELEASE_ID=$(echo "$EXISTING" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2) echo "Found existing release: $RELEASE_ID" else echo "Creating release..." RESPONSE=$(curl -s -X POST \ -H "Authorization: token ${{ secrets.RELEASE_TOKEN }}" \ -H "Content-Type: application/json" \ -d '{"tag_name":"'"$TAG"'","name":"Gitea '"$TAG"'","body":"Official release.","draft":false,"prerelease":false}' \ "${{ github.server_url }}/api/v1/repos/${{ github.repository }}/releases") RELEASE_ID=$(echo "$RESPONSE" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2) echo "Created release: $RELEASE_ID" fi # Upload files for file in dist/*; do if [ -f "$file" ]; then filename=$(basename "$file") # Delete existing asset if present ASSETS=$(curl -s -H "Authorization: token ${{ secrets.RELEASE_TOKEN }}" \ "${{ github.server_url }}/api/v1/repos/${{ github.repository }}/releases/$RELEASE_ID") ASSET_ID=$(echo "$ASSETS" | grep -o "\"id\":[0-9]*,\"name\":\"$filename\"" | grep -o '"id":[0-9]*' | cut -d: -f2) if [ -n "$ASSET_ID" ]; then echo "Deleting existing $filename" curl -s -X DELETE -H "Authorization: token ${{ secrets.RELEASE_TOKEN }}" \ "${{ github.server_url }}/api/v1/repos/${{ github.repository }}/releases/$RELEASE_ID/assets/$ASSET_ID" fi echo "Uploading $filename..." curl -s -X POST \ -H "Authorization: token ${{ secrets.RELEASE_TOKEN }}" \ -F "attachment=@$file" \ "${{ github.server_url }}/api/v1/repos/${{ github.repository }}/releases/$RELEASE_ID/assets?name=$filename" fi done