name: Release on: push: tags: - "v*" permissions: contents: write jobs: release: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - uses: actions/setup-go@v5 with: go-version-file: go.mod - uses: goreleaser/goreleaser-action@v6 with: version: "~> v2" args: release --clean env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SENTRY_DSN: ${{ secrets.SENTRY_DSN }} docker: needs: release runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Docker meta id: meta uses: docker/metadata-action@v5 with: images: torrentclaw/unarr tags: | type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=raw,value=latest - uses: docker/setup-qemu-action@v4 - uses: docker/setup-buildx-action@v3 - uses: docker/login-action@v4 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - uses: docker/build-push-action@v7 with: context: . push: true platforms: linux/amd64,linux/arm64 tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} build-args: | VERSION=${{ github.ref_name }} virustotal: needs: release runs-on: ubuntu-latest if: vars.VT_ENABLED == 'true' steps: - name: Get release tag id: tag run: echo "tag=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT" - name: Download release assets env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | mkdir -p assets gh release download "${{ steps.tag.outputs.tag }}" \ --repo "${{ github.repository }}" \ --dir assets \ --pattern '*.tar.gz' \ --pattern '*.zip' \ --pattern 'checksums.txt' - name: Scan assets with VirusTotal env: VT_API_KEY: ${{ secrets.VT_API_KEY }} run: | mkdir -p results for file in assets/*; do filename=$(basename "$file") echo "Uploading $filename to VirusTotal..." response=$(curl -s --request POST \ --url https://www.virustotal.com/api/v3/files \ --header "x-apikey: $VT_API_KEY" \ --form "file=@$file") analysis_id=$(echo "$response" | jq -r '.data.id // empty') if [ -z "$analysis_id" ]; then echo "::warning::Failed to upload $filename: $response" continue fi echo "$filename=$analysis_id" >> results/scans.txt echo " Analysis ID: $analysis_id" # Rate limit: VT free tier allows 4 req/min sleep 16 done - name: Wait for analysis completion env: VT_API_KEY: ${{ secrets.VT_API_KEY }} run: | echo "Waiting 60s for VirusTotal analysis to complete..." sleep 60 vt_report="## 🛡️ VirusTotal Scan Results\n\n" vt_report+="| File | Result | Link |\n" vt_report+="|------|--------|------|\n" while IFS='=' read -r filename analysis_id; do result=$(curl -s --request GET \ --url "https://www.virustotal.com/api/v3/analyses/$analysis_id" \ --header "x-apikey: $VT_API_KEY") malicious=$(echo "$result" | jq -r '.data.attributes.stats.malicious // 0') undetected=$(echo "$result" | jq -r '.data.attributes.stats.undetected // 0') sha256=$(echo "$result" | jq -r '.meta.file_info.sha256 // empty') if [ "$malicious" = "0" ]; then status="✅ Clean ($undetected engines)" else status="⚠️ $malicious detections" fi link="https://www.virustotal.com/gui/file/$sha256" vt_report+="| \`$filename\` | $status | [View]($link) |\n" sleep 16 done < results/scans.txt echo -e "$vt_report" > results/report.md cat results/report.md - name: Append scan results to release notes env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | current_body=$(gh release view "${{ steps.tag.outputs.tag }}" \ --repo "${{ github.repository }}" \ --json body --jq '.body') new_body="${current_body} $(cat results/report.md)" gh release edit "${{ steps.tag.outputs.tag }}" \ --repo "${{ github.repository }}" \ --notes "$new_body"