metadata change #56
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [main] | |
| tags: ["v*"] | |
| pull_request: | |
| branches: [main] | |
| permissions: | |
| contents: read | |
| jobs: | |
| # Check if source files changed | |
| check-src-changed: | |
| name: Check src/ changes | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| outputs: | |
| src_changed: ${{ steps.changes.outputs.src_changed }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Check if src/ changed | |
| id: changes | |
| run: | | |
| if [ "${{ github.event.before }}" = "0000000000000000000000000000000000000000" ]; then | |
| CHANGED_FILES=$(git diff --name-only HEAD~1) | |
| else | |
| CHANGED_FILES=$(git diff --name-only ${{ github.event.before }} ${{ github.event.after }}) | |
| fi | |
| echo "Changed files:" | |
| echo "$CHANGED_FILES" | |
| if echo "$CHANGED_FILES" | grep -q '^src/'; then | |
| echo "src_changed=true" >> $GITHUB_OUTPUT | |
| echo "✅ Source files changed - will create release" | |
| else | |
| echo "src_changed=false" >> $GITHUB_OUTPUT | |
| echo "❌ No src/ changes - skipping release" | |
| fi | |
| # Job 1: Windows x86 | |
| build-windows: | |
| name: Build Windows x86 | |
| runs-on: windows-latest | |
| needs: check-src-changed | |
| if: needs.check-src-changed.outputs.src_changed == 'true' || startsWith(github.ref, 'refs/tags/v') | |
| permissions: | |
| contents: read | |
| actions: read | |
| outputs: | |
| version: ${{ steps.gitversion.outputs.SemVer }} | |
| semver: ${{ steps.gitversion.outputs.SemVer }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup GitVersion | |
| uses: gittools/actions/gitversion/setup@v4 | |
| with: | |
| versionSpec: "6.5.1" | |
| - name: Run GitVersion | |
| id: gitversion | |
| uses: gittools/actions/gitversion/execute@v4 | |
| with: | |
| configFilePath: GitVersion.yml | |
| - name: Install MSYS2 & MinGW32 | |
| uses: msys2/setup-msys2@v2 | |
| with: | |
| update: true | |
| install: >- | |
| base-devel | |
| mingw-w64-i686-toolchain | |
| msystem: MINGW32 | |
| - name: Generate version header | |
| shell: bash | |
| run: | | |
| VERSION_FULL="${{ steps.gitversion.outputs.SemVer }}" | |
| echo "VERSION_FULL=${VERSION_FULL}" | |
| mkdir -p src/lib | |
| cat > src/lib/version.h <<EOF | |
| #ifndef PINGDD_VERSION_H | |
| #define PINGDD_VERSION_H | |
| #define PINGDD_VERSION "${VERSION_FULL}" | |
| #define PINGDD_VERSION_FULL "${VERSION_FULL}" | |
| #endif /* PINGDD_VERSION_H */ | |
| EOF | |
| - name: Generate Windows version.rc | |
| shell: bash | |
| run: | | |
| VERSION_FULL="${{ steps.gitversion.outputs.SemVer }}" | |
| MAJOR="${VERSION_FULL%%.*}" | |
| REST="${VERSION_FULL#*.}" | |
| MINOR="${REST%%.*}" | |
| REST="${REST#*.}" | |
| PATCH="${REST%%.*}" | |
| BUILD=0 | |
| cat > version.rc <<EOF | |
| #include <windows.h> | |
| IDI_MAIN_ICON ICON "pic/icon/PingDD Icon Small.ico" | |
| #define VER_FILEVERSION ${MAJOR},${MINOR},${PATCH},${BUILD} | |
| #define VER_FILEVERSION_STR "${VERSION_FULL}\0" | |
| #define VER_PRODUCTVERSION ${MAJOR},${MINOR},${PATCH},${BUILD} | |
| #define VER_PRODUCTVERSION_STR "${VERSION_FULL}\0" | |
| #define VER_COMPANYNAME_STR "DarthDemono\0" | |
| #define VER_FILEDESCRIPTION_STR "PingDD is a cross-platform ping tool for TCP port checking.\0" | |
| #define VER_INTERNALNAME_STR "PingDD\0" | |
| #define VER_LEGALCOPYRIGHT_STR "Copyright (c) 2025 DarthDemono\0" | |
| #define VER_ORIGINALFILENAME_STR "pingdd.exe\0" | |
| #define VER_PRODUCTNAME_STR "PingDD\0" | |
| VS_VERSION_INFO VERSIONINFO | |
| FILEVERSION VER_FILEVERSION | |
| PRODUCTVERSION VER_PRODUCTVERSION | |
| FILEFLAGSMASK 0x3fL | |
| FILEFLAGS 0x0L | |
| FILEOS VOS__WINDOWS32 | |
| FILETYPE VFT_APP | |
| FILESUBTYPE VFT2_UNKNOWN | |
| BEGIN | |
| BLOCK "StringFileInfo" | |
| BEGIN | |
| BLOCK "040904E4" | |
| BEGIN | |
| VALUE "CompanyName", VER_COMPANYNAME_STR | |
| VALUE "FileDescription", VER_FILEDESCRIPTION_STR | |
| VALUE "FileVersion", VER_FILEVERSION_STR | |
| VALUE "InternalName", VER_INTERNALNAME_STR | |
| VALUE "LegalCopyright", VER_LEGALCOPYRIGHT_STR | |
| VALUE "OriginalFilename", VER_ORIGINALFILENAME_STR | |
| VALUE "ProductName", VER_PRODUCTNAME_STR | |
| VALUE "ProductVersion", VER_PRODUCTVERSION_STR | |
| END | |
| END | |
| BLOCK "VarFileInfo" | |
| BEGIN | |
| VALUE "Translation", 0x0409, 1200 | |
| END | |
| END | |
| EOF | |
| - name: Build PingDD (32-bit) | |
| shell: msys2 {0} | |
| run: | | |
| echo "Using gcc:" | |
| gcc --version | |
| make clean | |
| make win32 | |
| - name: Self-sign executable (Windows SDK) | |
| if: success() && runner.os == 'Windows' | |
| shell: pwsh | |
| run: | | |
| choco install windows-sdk-10.0 -y --force | |
| refreshenv | |
| $signToolPaths = @( | |
| "${env:ProgramFiles(x86)}\Windows Kits\10\bin\10.0.26621.0\x64\signtool.exe", | |
| "${env:ProgramFiles(x86)}\Windows Kits\10\bin\x64\signtool.exe" | |
| ) | |
| $signtool = $null | |
| foreach ($path in $signToolPaths) { | |
| if (Test-Path $path) { | |
| $signtool = $path | |
| Write-Output "✅ Found SignTool: $signtool" | |
| break | |
| } | |
| } | |
| $env:PATH += ";$($signtool | Split-Path -Parent)" | |
| $cert = New-SelfSignedCertificate -Subject "CN=DarthDemono" ` | |
| -Type CodeSigningCert ` | |
| -CertStoreLocation Cert:\CurrentUser\My ` | |
| -KeyLength 2048 ` | |
| -HashAlgorithm SHA256 | |
| & $signtool sign /n "DarthDemono" /tr http://timestamp.digicert.com /td sha256 bin/win/pingdd.exe | |
| echo "✅ Self-signed: bin/win/pingdd.exe" | |
| - name: Upload Windows artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: pingdd-win32-${{ steps.gitversion.outputs.SemVer }}-signed | |
| path: bin/win/pingdd.exe | |
| # Job 2: Multi-Distro Linux (FIXED) | |
| build-linux: | |
| name: Build Linux (${{ matrix.distro_name }}) | |
| runs-on: ubuntu-latest | |
| needs: check-src-changed | |
| if: needs.check-src-changed.outputs.src_changed == 'true' || startsWith(github.ref, 'refs/tags/v') | |
| permissions: | |
| contents: read | |
| actions: read | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - distro: ubuntu:24.04 | |
| distro_name: ubuntu-24.04 | |
| - distro: ubuntu:22.04 | |
| distro_name: ubuntu-22.04 | |
| - distro: debian:bookworm | |
| distro_name: debian-bookworm | |
| - distro: debian:bullseye | |
| distro_name: debian-bullseye | |
| - distro: fedora:40 | |
| distro_name: fedora-40 | |
| - distro: alpine:3.19 | |
| distro_name: alpine-3.19 | |
| - distro: quay.io/centos/centos:stream9 | |
| distro_name: centos-stream9 | |
| outputs: | |
| version: ${{ steps.gitversion.outputs.SemVer }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup GitVersion | |
| uses: gittools/actions/gitversion/setup@v4 | |
| with: | |
| versionSpec: "6.5.1" | |
| - name: Run GitVersion | |
| id: gitversion | |
| uses: gittools/actions/gitversion/execute@v4 | |
| with: | |
| configFilePath: GitVersion.yml | |
| - name: Generate version header | |
| run: | | |
| VERSION_FULL="${{ steps.gitversion.outputs.SemVer }}" | |
| echo "VERSION_FULL=${VERSION_FULL}" | |
| mkdir -p src/lib | |
| cat > src/lib/version.h <<EOF | |
| #ifndef PINGDD_VERSION_H | |
| #define PINGDD_VERSION_H | |
| #define PINGDD_VERSION "${VERSION_FULL}" | |
| #define PINGDD_VERSION_FULL "${VERSION_FULL}" | |
| #endif /* PINGDD_VERSION_H */ | |
| EOF | |
| - name: Build on ${{ matrix.distro }} | |
| run: | | |
| docker run --rm \ | |
| -v "${{ github.workspace }}:/workspace" \ | |
| -w /workspace \ | |
| --network=host \ | |
| -e EXEC_SUFFIX="-${{ matrix.distro_name }}" \ | |
| ${{ matrix.distro }} \ | |
| /bin/sh -c ' | |
| # Update package lists first | |
| if command -v apt-get >/dev/null 2>&1; then | |
| apt-get update -qq || apt-get update -qq --fix-missing || true | |
| apt-get install -y --no-install-recommends gcc make libc6-dev | |
| elif command -v apk >/dev/null 2>&1; then | |
| apk add --no-cache gcc musl-dev make | |
| elif command -v dnf >/dev/null 2>&1; then | |
| dnf install -y gcc make glibc-devel | |
| elif command -v yum >/dev/null 2>&1; then | |
| yum install -y gcc make glibc-devel | |
| fi | |
| echo "GCC version:" | |
| gcc --version || echo "GCC not found, retrying install..." | |
| make clean | |
| make linux | |
| ' | |
| - name: Upload ${{ matrix.distro_name }} artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: pingdd-${{ matrix.distro_name }}-${{ steps.gitversion.outputs.SemVer }} | |
| path: bin/linux/pingdd-${{ matrix.distro_name }} | |
| # Job 3: Create Release + Publish to WinGet | |
| release: | |
| name: Publish Release & WinGet | |
| needs: [check-src-changed, build-windows, build-linux] | |
| if: | | |
| (needs.check-src-changed.outputs.src_changed == 'true' && github.ref == 'refs/heads/main') || | |
| startsWith(github.ref, 'refs/tags/v') | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| actions: read | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Get commit history since last release | |
| id: changelog | |
| run: | | |
| PREV_TAG=$(git describe --tags --abbrev=0 $(git rev-list --tags --max-count=1) 2>/dev/null || echo "") | |
| if [ -n "$PREV_TAG" ]; then | |
| git log --pretty=format:"- %s (%an)" $PREV_TAG..HEAD > commits.txt | |
| else | |
| git log --pretty=format:"- %s (%an)" HEAD~10..HEAD > commits.txt | |
| fi | |
| COMMITS=$(cat commits.txt) | |
| echo "commits<<EOF" >> $GITHUB_OUTPUT | |
| echo "$COMMITS" >> $GITHUB_OUTPUT | |
| echo "EOF" >> $GITHUB_OUTPUT | |
| echo "Previous tag: $PREV_TAG" | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: artifacts/ | |
| pattern: pingdd-* | |
| - name: List artifacts | |
| run: | | |
| echo "=== Artifacts structure ===" | |
| ls -laR artifacts/ | |
| - name: Prepare release assets | |
| run: | | |
| mkdir -p release-assets | |
| VERSION="${{ needs.build-windows.outputs.semver }}" | |
| # Windows: rename to clean 'pingdd.exe' | |
| cp artifacts/pingdd-win32-${VERSION}-signed/pingdd.exe release-assets/pingdd.exe | |
| echo "✅ Created pingdd.exe" | |
| # Linux: create individual ZIP files per distro | |
| for artifact_dir in artifacts/pingdd-*-${VERSION}/; do | |
| if [[ $artifact_dir == *"win32"* ]]; then | |
| continue | |
| fi | |
| # Extract distro name | |
| artifact_basename=$(basename "$artifact_dir") | |
| distro_name="${artifact_basename#pingdd-}" | |
| distro_name="${distro_name%-${VERSION}}" | |
| # Create ZIP with clean name inside | |
| cd "$artifact_dir" | |
| zip "../release-assets/pingdd-${distro_name}.zip" pingdd-* | |
| cd - > /dev/null | |
| echo "✅ Created pingdd-${distro_name}.zip" | |
| done | |
| echo "=== Final release assets ===" | |
| ls -lh release-assets/ | |
| - name: Create GitHub Release | |
| id: release | |
| uses: ncipollo/release-action@v1 | |
| with: | |
| tag: v${{ needs.build-windows.outputs.semver }} | |
| name: PingDD ${{ needs.build-windows.outputs.semver }} | |
| body: | | |
| # PingDD ${{ needs.build-windows.outputs.semver }} | |
| ## Downloads | |
| ### Windows | |
| - `pingdd.exe` - Windows 32-bit (self-signed) | |
| ### Linux Distributions | |
| - `pingdd-ubuntu-24.04.zip` - Ubuntu 24.04 | |
| - `pingdd-ubuntu-22.04.zip` - Ubuntu 22.04 | |
| - `pingdd-debian-bookworm.zip` - Debian Bookworm | |
| - `pingdd-debian-bullseye.zip` - Debian Bullseye | |
| - `pingdd-fedora-40.zip` - Fedora 40 | |
| - `pingdd-alpine-3.19.zip` - Alpine 3.19 | |
| - `pingdd-centos-stream9.zip` - CentOS Stream 9 | |
| ### Changes | |
| ${{ steps.changelog.outputs.commits }} | |
| artifacts: "release-assets/*" | |
| artifactContentType: application/zip | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| generateReleaseNotes: true | |
| allowUpdates: true | |
| replacesArtifacts: true | |
| draft: false | |
| prerelease: false |