mirror of
				https://github.com/masonr/yet-another-bench-script.git
				synced 2025-10-30 21:36:17 +00:00 
			
		
		
		
	add build workflows for fio/iperf3 updates
This commit is contained in:
		
							
								
								
									
										360
									
								
								.github/workflows/build-fio.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										360
									
								
								.github/workflows/build-fio.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,360 @@ | ||||
| name: Build fio Static Binaries | ||||
|  | ||||
| on: | ||||
|   workflow_dispatch: | ||||
|  | ||||
| jobs: | ||||
|   check-release: | ||||
|     runs-on: ubuntu-latest | ||||
|     outputs: | ||||
|       latest-version: ${{ steps.get-version.outputs.version }} | ||||
|       should-build: ${{ steps.check-version.outputs.should-build }} | ||||
|     steps: | ||||
|       - name: Checkout repository | ||||
|         uses: actions/checkout@v4 | ||||
|  | ||||
|       - name: Get latest fio release | ||||
|         id: get-version | ||||
|         run: | | ||||
|           # Get the latest release tag from GitHub API | ||||
|           LATEST_VERSION=$(curl -s https://api.github.com/repos/axboe/fio/releases/latest | jq -r '.tag_name') | ||||
|           echo "Latest fio version: $LATEST_VERSION" | ||||
|           echo "version=$LATEST_VERSION" >> $GITHUB_OUTPUT | ||||
|  | ||||
|       - name: Check if version exists in releases | ||||
|         id: check-version | ||||
|         run: | | ||||
|           VERSION="${{ steps.get-version.outputs.version }}" | ||||
|            | ||||
|           # Check if this version already exists in our releases | ||||
|           if gh release view "fio-$VERSION" --repo ${{ github.repository }} >/dev/null 2>&1; then | ||||
|             echo "Version $VERSION already exists in releases" | ||||
|             echo "should-build=false" >> $GITHUB_OUTPUT | ||||
|           else | ||||
|             echo "Version $VERSION does not exist, should build" | ||||
|             echo "should-build=true" >> $GITHUB_OUTPUT | ||||
|           fi | ||||
|         env: | ||||
|           GH_TOKEN: ${{ github.token }} | ||||
|  | ||||
|   build: | ||||
|     needs: check-release | ||||
|     if: needs.check-release.outputs.should-build == 'true' | ||||
|     runs-on: ubuntu-latest | ||||
|     strategy: | ||||
|       matrix: | ||||
|         include: | ||||
|           - arch: x64 | ||||
|             cross: x86_64-linux-musl | ||||
|             host: x86_64-linux-musl | ||||
|           - arch: x86 | ||||
|             cross: i686-linux-musl | ||||
|             host: i686-linux-musl | ||||
|           - arch: aarch64 | ||||
|             cross: aarch64-linux-musl | ||||
|             host: aarch64-linux-gnu | ||||
|           - arch: arm | ||||
|             cross: arm-linux-musleabihf | ||||
|             host: arm-linux-gnueabihf | ||||
|  | ||||
|     steps: | ||||
|       - name: Checkout repository | ||||
|         uses: actions/checkout@v4 | ||||
|  | ||||
|       - name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|  | ||||
|       - name: Create compilation script | ||||
|         run: | | ||||
|           VERSION="${{ needs.check-release.outputs.latest-version }}" | ||||
|           ARCH="${{ matrix.arch }}" | ||||
|           CROSS="${{ matrix.cross }}" | ||||
|           HOST="${{ matrix.host }}" | ||||
|            | ||||
|           # Single script for all architectures using musl cross-compilation | ||||
|           cat > compile-fio.sh << EOF | ||||
|           #!/bin/bash | ||||
|           set -e | ||||
|            | ||||
|           # Activate Holy Build Box lib compilation environment | ||||
|           source /hbb/activate | ||||
|            | ||||
|           set -x  | ||||
|            | ||||
|           # remove obsolete CentOS repos | ||||
|           cd /etc/yum.repos.d/ | ||||
|           rm -f CentOS-Base.repo CentOS-SCLo-scl-rh.repo CentOS-SCLo-scl.repo CentOS-fasttrack.repo CentOS-x86_64-kernel.repo | ||||
|            | ||||
|           yum install -y yum-plugin-ovl # fix for docker overlay fs | ||||
|           yum install -y xz | ||||
|            | ||||
|           # download musl cross compilation toolchain | ||||
|           cd ~ | ||||
|           curl -L "https://musl.cc/\$CROSS-cross.tgz" -o "\$CROSS-cross.tgz" | ||||
|           tar xf "\$CROSS-cross.tgz" | ||||
|            | ||||
|           # download, compile, and install libaio as static library | ||||
|           cd ~ | ||||
|           curl -L http://ftp.de.debian.org/debian/pool/main/liba/libaio/libaio_0.3.113.orig.tar.gz -o "libaio.tar.gz" | ||||
|           tar xf libaio.tar.gz | ||||
|           cd libaio-*/src | ||||
|           CC=/root/\$CROSS-cross/bin/\$CROSS-gcc ENABLE_SHARED=0 make prefix=/hbb_exe install | ||||
|            | ||||
|           # Activate Holy Build Box exe compilation environment | ||||
|           source /hbb_exe/activate | ||||
|            | ||||
|           # download and compile fio | ||||
|           cd ~ | ||||
|           curl -L "https://github.com/axboe/fio/archive/\$VERSION.tar.gz" -o "fio.tar.gz" | ||||
|           tar xf fio.tar.gz | ||||
|           cd fio-\${VERSION#fio-}* | ||||
|           CC=/root/\$CROSS-cross/bin/\$CROSS-gcc ./configure --disable-native --build-static | ||||
|           make | ||||
|            | ||||
|           # verify no external shared library links | ||||
|           libcheck fio | ||||
|           # copy fio binary to mounted dir | ||||
|           cp fio "/io/fio_\$ARCH" | ||||
|           EOF | ||||
|            | ||||
|           chmod +x compile-fio.sh | ||||
|  | ||||
|       - name: Compile fio binary | ||||
|         run: | | ||||
|           ARCH="${{ matrix.arch }}" | ||||
|           CROSS="${{ matrix.cross }}" | ||||
|           HOST="${{ matrix.host }}" | ||||
|            | ||||
|           # Use musl cross-compilation for all architectures | ||||
|           docker run -t -i --rm -v $(pwd):/io --env ARCH=$ARCH --env CROSS=$CROSS --env HOST=$HOST --env VERSION="${{ needs.check-release.outputs.latest-version }}" phusion/holy-build-box-64:latest bash /io/compile-fio.sh | ||||
|  | ||||
|       - name: Verify binary | ||||
|         run: | | ||||
|           ARCH="${{ matrix.arch }}" | ||||
|           ls -la fio_$ARCH | ||||
|           file fio_$ARCH | ||||
|  | ||||
|       - name: Upload binary as artifact | ||||
|         uses: actions/upload-artifact@v4 | ||||
|         with: | ||||
|           name: fio_${{ matrix.arch }} | ||||
|           path: fio_${{ matrix.arch }} | ||||
|           retention-days: 1 | ||||
|  | ||||
|   virustotal-scan: | ||||
|     needs: [check-release, build] | ||||
|     if: needs.check-release.outputs.should-build == 'true' | ||||
|     runs-on: ubuntu-latest | ||||
|     outputs: | ||||
|       scan-results: ${{ steps.scan-summary.outputs.results }} | ||||
|       all-clean: ${{ steps.scan-summary.outputs.all-clean }} | ||||
|     steps: | ||||
|       - name: Download all artifacts | ||||
|         uses: actions/download-artifact@v4 | ||||
|         with: | ||||
|           path: artifacts | ||||
|  | ||||
|       - name: Prepare binaries for scanning | ||||
|         run: | | ||||
|           mkdir -p scan-binaries | ||||
|           find artifacts -name "fio_*" -type f -exec cp {} scan-binaries/ \; | ||||
|           ls -la scan-binaries/ | ||||
|  | ||||
|       - name: Upload binaries to VirusTotal and scan | ||||
|         id: virustotal-upload | ||||
|         run: | | ||||
|           echo "## VirusTotal Scan Results" > scan_results.md | ||||
|           echo "| Binary | Status | Malicious | Suspicious | Undetected | VirusTotal URL |" >> scan_results.md | ||||
|           echo "|--------|--------|-----------|------------|------------|----------------|" >> scan_results.md | ||||
|            | ||||
|           ALL_CLEAN=true | ||||
|           SCAN_DATA="" | ||||
|            | ||||
|           for binary in scan-binaries/fio_*; do | ||||
|             filename=$(basename "$binary") | ||||
|             echo "Uploading $filename to VirusTotal..." | ||||
|              | ||||
|             # Upload to VirusTotal | ||||
|             upload_response=$(curl -s --request POST \ | ||||
|               --url https://www.virustotal.com/api/v3/files \ | ||||
|               --header 'accept: application/json' \ | ||||
|               --header 'content-type: multipart/form-data' \ | ||||
|               --header "x-apikey: ${{ secrets.VIRUSTOTAL_API_KEY }}" \ | ||||
|               --form "file=@$binary") | ||||
|              | ||||
|             analysis_id=$(echo "$upload_response" | jq -r '.data.id') | ||||
|             echo "Analysis ID for $filename: $analysis_id" | ||||
|              | ||||
|             if [ "$analysis_id" = "null" ] || [ -z "$analysis_id" ]; then | ||||
|               echo "Failed to upload $filename to VirusTotal" | ||||
|               echo "| $filename | Upload Failed | N/A | N/A | N/A | N/A |" >> scan_results.md | ||||
|               ALL_CLEAN=false | ||||
|               continue | ||||
|             fi | ||||
|              | ||||
|             # Store analysis ID for later retrieval | ||||
|             echo "${filename}:${analysis_id}" >> analysis_ids.txt | ||||
|           done | ||||
|            | ||||
|           echo "all_clean_upload=$ALL_CLEAN" >> $GITHUB_OUTPUT | ||||
|            | ||||
|           # Wait 2 minutes for scans to complete | ||||
|           echo "Waiting 2 minutes for VirusTotal scans to complete..." | ||||
|           sleep 120 | ||||
|  | ||||
|       - name: Retrieve VirusTotal scan results | ||||
|         id: get-results | ||||
|         run: | | ||||
|           ALL_CLEAN=true | ||||
|           SCAN_SUMMARY="" | ||||
|            | ||||
|           while IFS=':' read -r filename analysis_id; do | ||||
|             echo "Retrieving results for $filename (ID: $analysis_id)..." | ||||
|              | ||||
|             # Get scan results | ||||
|             result_response=$(curl -s --request GET \ | ||||
|               --url "https://www.virustotal.com/api/v3/analyses/$analysis_id" \ | ||||
|               --header 'accept: application/json' \ | ||||
|               --header "x-apikey: ${{ secrets.VIRUSTOTAL_API_KEY }}") | ||||
|              | ||||
|             status=$(echo "$result_response" | jq -r '.data.attributes.status // "unknown"') | ||||
|              | ||||
|             if [ "$status" = "completed" ]; then | ||||
|               malicious=$(echo "$result_response" | jq -r '.data.attributes.stats.malicious // 0') | ||||
|               suspicious=$(echo "$result_response" | jq -r '.data.attributes.stats.suspicious // 0') | ||||
|               undetected=$(echo "$result_response" | jq -r '.data.attributes.stats.undetected // 0') | ||||
|                | ||||
|               # Get file hash from the item link | ||||
|               item_link=$(echo "$result_response" | jq -r '.data.links.item // ""') | ||||
|               file_hash=$(echo "$item_link" | sed 's/.*files\///') | ||||
|               vt_url="https://www.virustotal.com/gui/file/$file_hash" | ||||
|                | ||||
|               if [ "$malicious" -gt 0 ] || [ "$suspicious" -gt 0 ]; then | ||||
|                 status_text="⚠️ FLAGGED" | ||||
|                 ALL_CLEAN=false | ||||
|               else | ||||
|                 status_text="✅ Clean" | ||||
|               fi | ||||
|                | ||||
|               echo "| $filename | $status_text | $malicious | $suspicious | $undetected | [$file_hash]($vt_url) |" >> scan_results.md | ||||
|                | ||||
|             else | ||||
|               echo "| $filename | ⏳ Pending | N/A | N/A | N/A | Scan not completed |" >> scan_results.md | ||||
|               ALL_CLEAN=false | ||||
|             fi | ||||
|              | ||||
|           done < analysis_ids.txt | ||||
|            | ||||
|           echo "all_clean=$ALL_CLEAN" >> $GITHUB_OUTPUT | ||||
|            | ||||
|           # Add summary to GitHub step summary | ||||
|           cat scan_results.md >> $GITHUB_STEP_SUMMARY | ||||
|  | ||||
|       - name: Create scan summary | ||||
|         id: scan-summary | ||||
|         run: | | ||||
|           RESULTS=$(cat scan_results.md) | ||||
|           ALL_CLEAN="${{ steps.get-results.outputs.all_clean }}" | ||||
|            | ||||
|           # Escape newlines for GitHub output | ||||
|           RESULTS_ESCAPED=$(echo "$RESULTS" | sed ':a;N;$!ba;s/\n/\\n/g') | ||||
|            | ||||
|           echo "results=$RESULTS_ESCAPED" >> $GITHUB_OUTPUT | ||||
|           echo "all-clean=$ALL_CLEAN" >> $GITHUB_OUTPUT | ||||
|  | ||||
|       - name: Upload scan results as artifact | ||||
|         uses: actions/upload-artifact@v4 | ||||
|         with: | ||||
|           name: virustotal-scan-results | ||||
|           path: | | ||||
|             scan_results.md | ||||
|             analysis_ids.txt | ||||
|           retention-days: 30 | ||||
|  | ||||
|   create-release: | ||||
|     needs: [check-release, build, virustotal-scan] | ||||
|     if: needs.check-release.outputs.should-build == 'true' && needs.virustotal-scan.outputs.all-clean == 'true' | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout repository | ||||
|         uses: actions/checkout@v4 | ||||
|  | ||||
|       - name: Download all artifacts | ||||
|         uses: actions/download-artifact@v4 | ||||
|         with: | ||||
|           path: artifacts | ||||
|  | ||||
|       - name: Prepare release assets | ||||
|         run: | | ||||
|           mkdir -p release-assets | ||||
|           # Move all binaries to release-assets directory | ||||
|           find artifacts -name "fio_*" -type f -exec cp {} release-assets/ \; | ||||
|           ls -la release-assets/ | ||||
|  | ||||
|       - name: Generate SHA256 checksums | ||||
|         run: | | ||||
|           cd release-assets | ||||
|           sha256sum fio_* > fio-checksums.sha256 | ||||
|           cat fio-checksums.sha256 | ||||
|  | ||||
|       - name: Download VirusTotal scan results | ||||
|         uses: actions/download-artifact@v4 | ||||
|         with: | ||||
|           name: virustotal-scan-results | ||||
|           path: vt-results | ||||
|  | ||||
|       - name: Create Release | ||||
|         uses: softprops/action-gh-release@v1 | ||||
|         with: | ||||
|           tag_name: fio-${{ needs.check-release.outputs.latest-version }} | ||||
|           name: fio ${{ needs.check-release.outputs.latest-version }} Static Binaries | ||||
|           body: | | ||||
|             Static binaries for fio ${{ needs.check-release.outputs.latest-version }} | ||||
|              | ||||
|             Built using musl toolchains for maximum compatibility. | ||||
|              | ||||
|             **Architectures:** | ||||
|             - `fio_x64` - x86_64 (64-bit) | ||||
|             - `fio_x86` - i686 (32-bit) | ||||
|             - `fio_aarch64` - ARM 64-bit | ||||
|             - `fio_arm` - ARM 32-bit | ||||
|              | ||||
|             **Security Verification:** | ||||
|             All binaries have been scanned by VirusTotal and verified clean. | ||||
|              | ||||
|             ${{ needs.virustotal-scan.outputs.scan-results }} | ||||
|              | ||||
|             **Checksum Verification:** | ||||
|             ```bash | ||||
|             # Verify checksums | ||||
|             sha256sum -c fio-checksums.sha256 | ||||
|             ``` | ||||
|              | ||||
|             For usage in YABS script, place these binaries in the `bin/fio/` directory. | ||||
|           files: | | ||||
|             release-assets/fio_* | ||||
|             release-assets/fio-checksums.sha256 | ||||
|           draft: false | ||||
|           prerelease: false | ||||
|         env: | ||||
|           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||||
|  | ||||
|   notify-failure: | ||||
|     needs: [check-release, build, virustotal-scan] | ||||
|     if: always() && needs.check-release.outputs.should-build == 'true' && (failure() || needs.virustotal-scan.outputs.all-clean == 'false') | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Send failure notification | ||||
|         run: | | ||||
|           echo "## ⚠️ fio Build Failed" >> $GITHUB_STEP_SUMMARY | ||||
|           echo "Version: ${{ needs.check-release.outputs.latest-version }}" >> $GITHUB_STEP_SUMMARY | ||||
|            | ||||
|           if [ "${{ needs.virustotal-scan.outputs.all-clean }}" == "false" ]; then | ||||
|             echo "**Reason:** VirusTotal scan detected issues with one or more binaries" >> $GITHUB_STEP_SUMMARY | ||||
|             echo "**Scan Results:**" >> $GITHUB_STEP_SUMMARY | ||||
|             echo "${{ needs.virustotal-scan.outputs.scan-results }}" >> $GITHUB_STEP_SUMMARY | ||||
|           else | ||||
|             echo "**Reason:** Build compilation failed" >> $GITHUB_STEP_SUMMARY | ||||
|           fi | ||||
|            | ||||
|           echo "Check the workflow logs for details: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" >> $GITHUB_STEP_SUMMARY | ||||
							
								
								
									
										388
									
								
								.github/workflows/build-iperf3.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										388
									
								
								.github/workflows/build-iperf3.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,388 @@ | ||||
| name: Build iperf3 Static Binaries | ||||
|  | ||||
| on: | ||||
|   workflow_dispatch: | ||||
|  | ||||
| jobs: | ||||
|   check-release: | ||||
|     runs-on: ubuntu-latest | ||||
|     outputs: | ||||
|       latest-version: ${{ steps.get-version.outputs.version }} | ||||
|       should-build: ${{ steps.check-version.outputs.should-build }} | ||||
|     steps: | ||||
|       - name: Checkout repository | ||||
|         uses: actions/checkout@v4 | ||||
|  | ||||
|       - name: Get latest iperf3 release | ||||
|         id: get-version | ||||
|         run: | | ||||
|           # Get the latest release tag from GitHub API | ||||
|           LATEST_VERSION=$(curl -s https://api.github.com/repos/esnet/iperf/releases/latest | jq -r '.tag_name') | ||||
|           echo "Latest iperf3 version: $LATEST_VERSION" | ||||
|           echo "version=$LATEST_VERSION" >> $GITHUB_OUTPUT | ||||
|  | ||||
|       - name: Check if version exists in releases | ||||
|         id: check-version | ||||
|         run: | | ||||
|           VERSION="${{ steps.get-version.outputs.version }}" | ||||
|            | ||||
|           # Check if this version already exists in our releases | ||||
|           if gh release view "iperf3-$VERSION" --repo ${{ github.repository }} >/dev/null 2>&1; then | ||||
|             echo "Version $VERSION already exists in releases" | ||||
|             echo "should-build=false" >> $GITHUB_OUTPUT | ||||
|           else | ||||
|             echo "Version $VERSION does not exist, should build" | ||||
|             echo "should-build=true" >> $GITHUB_OUTPUT | ||||
|           fi | ||||
|         env: | ||||
|           GH_TOKEN: ${{ github.token }} | ||||
|  | ||||
|   build: | ||||
|     needs: check-release | ||||
|     if: needs.check-release.outputs.should-build == 'true' | ||||
|     runs-on: ubuntu-latest | ||||
|     strategy: | ||||
|       matrix: | ||||
|         include: | ||||
|           - arch: x64 | ||||
|             cross: x86_64-linux-musl | ||||
|             host: x86_64-linux-musl | ||||
|           - arch: x86 | ||||
|             cross: i686-linux-musl | ||||
|             host: i686-linux-musl | ||||
|           - arch: aarch64 | ||||
|             cross: aarch64-linux-musl | ||||
|             host: aarch64-linux-gnu | ||||
|           # Note: ARM 32-bit compilation of iperf3 >3.15 has known issues | ||||
|           # We'll still attempt it but expect potential failures | ||||
|           - arch: arm | ||||
|             cross: arm-linux-musleabihf | ||||
|             host: arm-linux-gnueabihf | ||||
|  | ||||
|     steps: | ||||
|       - name: Checkout repository | ||||
|         uses: actions/checkout@v4 | ||||
|  | ||||
|       - name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|  | ||||
|       - name: Create compilation script | ||||
|         run: | | ||||
|           VERSION="${{ needs.check-release.outputs.latest-version }}" | ||||
|           ARCH="${{ matrix.arch }}" | ||||
|           CROSS="${{ matrix.cross }}" | ||||
|           HOST="${{ matrix.host }}" | ||||
|            | ||||
|           # Single script for all architectures using musl cross-compilation | ||||
|           cat > compile-iperf3.sh << EOF | ||||
|           #!/bin/bash | ||||
|           set -e | ||||
|            | ||||
|           # Activate Holy Build Box lib compilation environment | ||||
|           source /hbb/activate | ||||
|            | ||||
|           set -x  | ||||
|            | ||||
|           # remove obsolete CentOS repos | ||||
|           cd /etc/yum.repos.d/ | ||||
|           rm -f CentOS-Base.repo CentOS-SCLo-scl-rh.repo CentOS-SCLo-scl.repo CentOS-fasttrack.repo CentOS-x86_64-kernel.repo | ||||
|            | ||||
|           yum install -y yum-plugin-ovl # fix for docker overlay fs | ||||
|           yum install -y xz | ||||
|            | ||||
|           # download musl cross compilation toolchain | ||||
|           cd ~ | ||||
|           curl -L "https://musl.cc/\$CROSS-cross.tgz" -o "\$CROSS-cross.tgz" | ||||
|           tar xf "\$CROSS-cross.tgz" | ||||
|            | ||||
|           # Activate Holy Build Box exe compilation environment | ||||
|           source /hbb_exe/activate | ||||
|            | ||||
|           # download and compile iperf3 | ||||
|           cd ~ | ||||
|           curl -L "https://github.com/esnet/iperf/archive/\$VERSION.tar.gz" -o "iperf.tar.gz" | ||||
|           tar xf iperf.tar.gz | ||||
|           cd iperf-* | ||||
|           CC=/root/\$CROSS-cross/bin/\$CROSS-gcc ./configure --disable-shared --disable-profiling --build x86_64-pc-linux-gnu --host "\$HOST" --with-openssl=no --enable-static-bin | ||||
|           make | ||||
|            | ||||
|           # verify no external shared library links | ||||
|           libcheck src/iperf3 | ||||
|           # copy iperf3 binary to mounted dir | ||||
|           cp src/iperf3 "/io/iperf3_\$ARCH" | ||||
|           EOF | ||||
|            | ||||
|           chmod +x compile-iperf3.sh | ||||
|  | ||||
|       - name: Compile iperf3 binary | ||||
|         run: | | ||||
|           ARCH="${{ matrix.arch }}" | ||||
|           CROSS="${{ matrix.cross }}" | ||||
|           HOST="${{ matrix.host }}" | ||||
|            | ||||
|           # Use musl cross-compilation for all architectures | ||||
|           docker run -t -i --rm -v $(pwd):/io --env ARCH=$ARCH --env CROSS=$CROSS --env HOST=$HOST --env VERSION="${{ needs.check-release.outputs.latest-version }}" phusion/holy-build-box-64:latest bash /io/compile-iperf3.sh | ||||
|  | ||||
|       - name: Verify binary | ||||
|         run: | | ||||
|           ARCH="${{ matrix.arch }}" | ||||
|           ls -la iperf3_$ARCH | ||||
|           file iperf3_$ARCH | ||||
|  | ||||
|       - name: Upload binary as artifact | ||||
|         uses: actions/upload-artifact@v4 | ||||
|         with: | ||||
|           name: iperf3_${{ matrix.arch }} | ||||
|           path: iperf3_${{ matrix.arch }} | ||||
|           retention-days: 1 | ||||
|         # Allow arm builds to fail as ARM 32-bit has known compilation issues with newer versions | ||||
|         continue-on-error: ${{ matrix.arch == 'arm' }} | ||||
|  | ||||
|   virustotal-scan: | ||||
|     needs: [check-release, build] | ||||
|     if: needs.check-release.outputs.should-build == 'true' | ||||
|     runs-on: ubuntu-latest | ||||
|     outputs: | ||||
|       scan-results: ${{ steps.scan-summary.outputs.results }} | ||||
|       all-clean: ${{ steps.scan-summary.outputs.all-clean }} | ||||
|     steps: | ||||
|       - name: Download all artifacts | ||||
|         uses: actions/download-artifact@v4 | ||||
|         with: | ||||
|           path: artifacts | ||||
|         continue-on-error: true | ||||
|  | ||||
|       - name: Prepare binaries for scanning | ||||
|         run: | | ||||
|           mkdir -p scan-binaries | ||||
|           find artifacts -name "iperf3_*" -type f -exec cp {} scan-binaries/ \; || true | ||||
|           ls -la scan-binaries/ | ||||
|            | ||||
|           # Check if we have at least the x64 binary | ||||
|           if [ ! -f "scan-binaries/iperf3_x64" ]; then | ||||
|             echo "Error: No iperf3_x64 binary found" | ||||
|             exit 1 | ||||
|           fi | ||||
|  | ||||
|       - name: Upload binaries to VirusTotal and scan | ||||
|         id: virustotal-upload | ||||
|         run: | | ||||
|           echo "## VirusTotal Scan Results" > scan_results.md | ||||
|           echo "| Binary | Status | Malicious | Suspicious | Undetected | VirusTotal URL |" >> scan_results.md | ||||
|           echo "|--------|--------|-----------|------------|------------|----------------|" >> scan_results.md | ||||
|            | ||||
|           ALL_CLEAN=true | ||||
|           SCAN_DATA="" | ||||
|            | ||||
|           for binary in scan-binaries/iperf3_*; do | ||||
|             filename=$(basename "$binary") | ||||
|             echo "Uploading $filename to VirusTotal..." | ||||
|              | ||||
|             # Upload to VirusTotal | ||||
|             upload_response=$(curl -s --request POST \ | ||||
|               --url https://www.virustotal.com/api/v3/files \ | ||||
|               --header 'accept: application/json' \ | ||||
|               --header 'content-type: multipart/form-data' \ | ||||
|               --header "x-apikey: ${{ secrets.VIRUSTOTAL_API_KEY }}" \ | ||||
|               --form "file=@$binary") | ||||
|              | ||||
|             analysis_id=$(echo "$upload_response" | jq -r '.data.id') | ||||
|             echo "Analysis ID for $filename: $analysis_id" | ||||
|              | ||||
|             if [ "$analysis_id" = "null" ] || [ -z "$analysis_id" ]; then | ||||
|               echo "Failed to upload $filename to VirusTotal" | ||||
|               echo "| $filename | Upload Failed | N/A | N/A | N/A | N/A |" >> scan_results.md | ||||
|               ALL_CLEAN=false | ||||
|               continue | ||||
|             fi | ||||
|              | ||||
|             # Store analysis ID for later retrieval | ||||
|             echo "${filename}:${analysis_id}" >> analysis_ids.txt | ||||
|           done | ||||
|            | ||||
|           echo "all_clean_upload=$ALL_CLEAN" >> $GITHUB_OUTPUT | ||||
|            | ||||
|           # Wait 2 minutes for scans to complete | ||||
|           echo "Waiting 2 minutes for VirusTotal scans to complete..." | ||||
|           sleep 120 | ||||
|  | ||||
|       - name: Retrieve VirusTotal scan results | ||||
|         id: get-results | ||||
|         run: | | ||||
|           ALL_CLEAN=true | ||||
|           SCAN_SUMMARY="" | ||||
|            | ||||
|           while IFS=':' read -r filename analysis_id; do | ||||
|             echo "Retrieving results for $filename (ID: $analysis_id)..." | ||||
|              | ||||
|             # Get scan results | ||||
|             result_response=$(curl -s --request GET \ | ||||
|               --url "https://www.virustotal.com/api/v3/analyses/$analysis_id" \ | ||||
|               --header 'accept: application/json' \ | ||||
|               --header "x-apikey: ${{ secrets.VIRUSTOTAL_API_KEY }}") | ||||
|              | ||||
|             status=$(echo "$result_response" | jq -r '.data.attributes.status // "unknown"') | ||||
|              | ||||
|             if [ "$status" = "completed" ]; then | ||||
|               malicious=$(echo "$result_response" | jq -r '.data.attributes.stats.malicious // 0') | ||||
|               suspicious=$(echo "$result_response" | jq -r '.data.attributes.stats.suspicious // 0') | ||||
|               undetected=$(echo "$result_response" | jq -r '.data.attributes.stats.undetected // 0') | ||||
|                | ||||
|               # Get file hash from the item link | ||||
|               item_link=$(echo "$result_response" | jq -r '.data.links.item // ""') | ||||
|               file_hash=$(echo "$item_link" | sed 's/.*files\///') | ||||
|               vt_url="https://www.virustotal.com/gui/file/$file_hash" | ||||
|                | ||||
|               if [ "$malicious" -gt 0 ] || [ "$suspicious" -gt 0 ]; then | ||||
|                 status_text="⚠️ FLAGGED" | ||||
|                 ALL_CLEAN=false | ||||
|               else | ||||
|                 status_text="✅ Clean" | ||||
|               fi | ||||
|                | ||||
|               echo "| $filename | $status_text | $malicious | $suspicious | $undetected | [$file_hash]($vt_url) |" >> scan_results.md | ||||
|                | ||||
|             else | ||||
|               echo "| $filename | ⏳ Pending | N/A | N/A | N/A | Scan not completed |" >> scan_results.md | ||||
|               ALL_CLEAN=false | ||||
|             fi | ||||
|              | ||||
|           done < analysis_ids.txt | ||||
|            | ||||
|           echo "all_clean=$ALL_CLEAN" >> $GITHUB_OUTPUT | ||||
|            | ||||
|           # Add summary to GitHub step summary | ||||
|           cat scan_results.md >> $GITHUB_STEP_SUMMARY | ||||
|  | ||||
|       - name: Create scan summary | ||||
|         id: scan-summary | ||||
|         run: | | ||||
|           RESULTS=$(cat scan_results.md) | ||||
|           ALL_CLEAN="${{ steps.get-results.outputs.all_clean }}" | ||||
|            | ||||
|           # Escape newlines for GitHub output | ||||
|           RESULTS_ESCAPED=$(echo "$RESULTS" | sed ':a;N;$!ba;s/\n/\\n/g') | ||||
|            | ||||
|           echo "results=$RESULTS_ESCAPED" >> $GITHUB_OUTPUT | ||||
|           echo "all-clean=$ALL_CLEAN" >> $GITHUB_OUTPUT | ||||
|  | ||||
|       - name: Upload scan results as artifact | ||||
|         uses: actions/upload-artifact@v4 | ||||
|         with: | ||||
|           name: virustotal-scan-results | ||||
|           path: | | ||||
|             scan_results.md | ||||
|             analysis_ids.txt | ||||
|           retention-days: 30 | ||||
|  | ||||
|   create-release: | ||||
|     needs: [check-release, build, virustotal-scan] | ||||
|     if: needs.check-release.outputs.should-build == 'true' && needs.virustotal-scan.outputs.all-clean == 'true' | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout repository | ||||
|         uses: actions/checkout@v4 | ||||
|  | ||||
|       - name: Download all artifacts | ||||
|         uses: actions/download-artifact@v4 | ||||
|         with: | ||||
|           path: artifacts | ||||
|           # Continue even if some artifacts (like arm) failed | ||||
|         continue-on-error: true | ||||
|  | ||||
|       - name: Prepare release assets | ||||
|         run: | | ||||
|           mkdir -p release-assets | ||||
|           # Move all binaries to release-assets directory | ||||
|           find artifacts -name "iperf3_*" -type f -exec cp {} release-assets/ \; || true | ||||
|           ls -la release-assets/ | ||||
|            | ||||
|           # Check if we have at least the x64 binary | ||||
|           if [ ! -f "release-assets/iperf3_x64" ]; then | ||||
|             echo "Error: No iperf3_x64 binary found" | ||||
|             exit 1 | ||||
|           fi | ||||
|  | ||||
|       - name: Generate SHA256 checksums | ||||
|         run: | | ||||
|           cd release-assets | ||||
|           if ls iperf3_* 1> /dev/null 2>&1; then | ||||
|             sha256sum iperf3_* > iperf3-checksums.sha256 | ||||
|             cat iperf3-checksums.sha256 | ||||
|           else | ||||
|             echo "No iperf3 binaries found to checksum" | ||||
|             exit 1 | ||||
|           fi | ||||
|  | ||||
|       - name: Check for ARM binary and add note | ||||
|         id: check-arm | ||||
|         run: | | ||||
|           if [ -f "release-assets/iperf3_arm" ]; then | ||||
|             echo "arm-note=" >> $GITHUB_OUTPUT | ||||
|           else | ||||
|             echo "arm-note=**Note:** ARM 32-bit binary compilation failed (known issue with iperf3 versions >3.15). Other architectures compiled successfully." >> $GITHUB_OUTPUT | ||||
|           fi | ||||
|  | ||||
|       - name: Download VirusTotal scan results | ||||
|         uses: actions/download-artifact@v4 | ||||
|         with: | ||||
|           name: virustotal-scan-results | ||||
|           path: vt-results | ||||
|  | ||||
|       - name: Create Release | ||||
|         uses: softprops/action-gh-release@v1 | ||||
|         with: | ||||
|           tag_name: iperf3-${{ needs.check-release.outputs.latest-version }} | ||||
|           name: iperf3 ${{ needs.check-release.outputs.latest-version }} Static Binaries | ||||
|           body: | | ||||
|             Static binaries for iperf3 ${{ needs.check-release.outputs.latest-version }} | ||||
|              | ||||
|             Built using musl toolchains for maximum compatibility. | ||||
|              | ||||
|             **Architectures:** | ||||
|             - `iperf3_x64` - x86_64 (64-bit) | ||||
|             - `iperf3_x86` - i686 (32-bit) | ||||
|             - `iperf3_aarch64` - ARM 64-bit | ||||
|             - `iperf3_arm` - ARM 32-bit (if available) | ||||
|              | ||||
|             ${{ steps.check-arm.outputs.arm-note }} | ||||
|              | ||||
|             **Security Verification:** | ||||
|             All binaries have been scanned by VirusTotal and verified clean. | ||||
|              | ||||
|             ${{ needs.virustotal-scan.outputs.scan-results }} | ||||
|              | ||||
|             **Checksum Verification:** | ||||
|             ```bash | ||||
|             # Verify checksums | ||||
|             sha256sum -c iperf3-checksums.sha256 | ||||
|             ``` | ||||
|              | ||||
|             For usage in YABS script, place these binaries in the `bin/iperf/` directory. | ||||
|           files: | | ||||
|             release-assets/iperf3_* | ||||
|             release-assets/iperf3-checksums.sha256 | ||||
|           draft: false | ||||
|           prerelease: false | ||||
|         env: | ||||
|           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||||
|  | ||||
|   notify-failure: | ||||
|     needs: [check-release, build, virustotal-scan] | ||||
|     if: always() && needs.check-release.outputs.should-build == 'true' && (failure() || needs.virustotal-scan.outputs.all-clean == 'false') | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Send failure notification | ||||
|         run: | | ||||
|           echo "## ⚠️ iperf3 Build Failed" >> $GITHUB_STEP_SUMMARY | ||||
|           echo "Version: ${{ needs.check-release.outputs.latest-version }}" >> $GITHUB_STEP_SUMMARY | ||||
|            | ||||
|           if [ "${{ needs.virustotal-scan.outputs.all-clean }}" == "false" ]; then | ||||
|             echo "**Reason:** VirusTotal scan detected issues with one or more binaries" >> $GITHUB_STEP_SUMMARY | ||||
|             echo "**Scan Results:**" >> $GITHUB_STEP_SUMMARY | ||||
|             echo "${{ needs.virustotal-scan.outputs.scan-results }}" >> $GITHUB_STEP_SUMMARY | ||||
|           else | ||||
|             echo "**Reason:** Build compilation failed" >> $GITHUB_STEP_SUMMARY | ||||
|           fi | ||||
|            | ||||
|           echo "Check the workflow logs for details: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" >> $GITHUB_STEP_SUMMARY | ||||
							
								
								
									
										74
									
								
								.github/workflows/monitor-releases.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								.github/workflows/monitor-releases.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,74 @@ | ||||
| name: Monitor External Releases for Updates | ||||
|  | ||||
| on: | ||||
|   schedule: | ||||
|     # Check every hour for new releases | ||||
|     - cron: '0 * * * *' | ||||
|   workflow_dispatch: | ||||
|  | ||||
| jobs: | ||||
|   monitor-releases: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout repository | ||||
|         uses: actions/checkout@v4 | ||||
|  | ||||
|       - name: Check fio releases | ||||
|         id: check-fio | ||||
|         run: | | ||||
|           # Get latest fio release | ||||
|           LATEST_FIO=$(curl -s https://api.github.com/repos/axboe/fio/releases/latest | jq -r '.tag_name') | ||||
|           echo "Latest fio: $LATEST_FIO" | ||||
|            | ||||
|           # Check if we already have this version | ||||
|           if ! gh release view "fio-$LATEST_FIO" --repo ${{ github.repository }} >/dev/null 2>&1; then | ||||
|             echo "New fio version found: $LATEST_FIO" | ||||
|             echo "trigger-fio=true" >> $GITHUB_OUTPUT | ||||
|             echo "fio-version=$LATEST_FIO" >> $GITHUB_OUTPUT | ||||
|           else | ||||
|             echo "fio $LATEST_FIO already exists" | ||||
|             echo "trigger-fio=false" >> $GITHUB_OUTPUT | ||||
|           fi | ||||
|         env: | ||||
|           GH_TOKEN: ${{ github.token }} | ||||
|  | ||||
|       - name: Check iperf3 releases | ||||
|         id: check-iperf3 | ||||
|         run: | | ||||
|           # Get latest iperf3 release | ||||
|           LATEST_IPERF3=$(curl -s https://api.github.com/repos/esnet/iperf/releases/latest | jq -r '.tag_name') | ||||
|           echo "Latest iperf3: $LATEST_IPERF3" | ||||
|            | ||||
|           # Check if we already have this version | ||||
|           if ! gh release view "iperf3-$LATEST_IPERF3" --repo ${{ github.repository }} >/dev/null 2>&1; then | ||||
|             echo "New iperf3 version found: $LATEST_IPERF3" | ||||
|             echo "trigger-iperf3=true" >> $GITHUB_OUTPUT | ||||
|             echo "iperf3-version=$LATEST_IPERF3" >> $GITHUB_OUTPUT | ||||
|           else | ||||
|             echo "iperf3 $LATEST_IPERF3 already exists" | ||||
|             echo "trigger-iperf3=false" >> $GITHUB_OUTPUT | ||||
|           fi | ||||
|         env: | ||||
|           GH_TOKEN: ${{ github.token }} | ||||
|  | ||||
|       - name: Trigger fio build workflow | ||||
|         if: steps.check-fio.outputs.trigger-fio == 'true' | ||||
|         run: | | ||||
|           echo "Triggering fio build for version ${{ steps.check-fio.outputs.fio-version }}" | ||||
|           gh workflow run build-fio.yml --repo ${{ github.repository }} | ||||
|         env: | ||||
|           GH_TOKEN: ${{ github.token }} | ||||
|  | ||||
|       - name: Trigger iperf3 build workflow | ||||
|         if: steps.check-iperf3.outputs.trigger-iperf3 == 'true' | ||||
|         run: | | ||||
|           echo "Triggering iperf3 build for version ${{ steps.check-iperf3.outputs.iperf3-version }}" | ||||
|           gh workflow run build-iperf3.yml --repo ${{ github.repository }} | ||||
|         env: | ||||
|           GH_TOKEN: ${{ github.token }} | ||||
|  | ||||
|       - name: Summary | ||||
|         run: | | ||||
|           echo "## Release Monitoring Summary" >> $GITHUB_STEP_SUMMARY | ||||
|           echo "- fio: ${{ steps.check-fio.outputs.trigger-fio == 'true' && 'New version triggered build' || 'No new version' }}" >> $GITHUB_STEP_SUMMARY | ||||
|           echo "- iperf3: ${{ steps.check-iperf3.outputs.trigger-iperf3 == 'true' && 'New version triggered build' || 'No new version' }}" >> $GITHUB_STEP_SUMMARY | ||||
		Reference in New Issue
	
	Block a user