Repository navigation
ci: add vglyph checks #8
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 Checks | |
| on: | |
| push: | |
| paths: | |
| - "**.v" | |
| - "**.vsh" | |
| - "**.c" | |
| - "**.h" | |
| - "**.m" | |
| - "**.md" | |
| - "v.mod" | |
| - "assets/**" | |
| - ".github/workflows/*.yml" | |
| pull_request: | |
| paths: | |
| - "**.v" | |
| - "**.vsh" | |
| - "**.c" | |
| - "**.h" | |
| - "**.m" | |
| - "**.md" | |
| - "v.mod" | |
| - "assets/**" | |
| - ".github/workflows/*.yml" | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| CORE_PKG_CONFIG_MODULES: freetype2 harfbuzz fribidi fontconfig pango pangoft2 gobject-2.0 glib-2.0 | |
| jobs: | |
| linux: | |
| name: CI Checks / Linux | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 70 | |
| env: | |
| VFLAGS: -no-parallel | |
| VJOBS: 1 | |
| steps: | |
| - name: Checkout vglyph | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Install V | |
| uses: vlang/setup-v@v1.4 | |
| with: | |
| check-latest: true | |
| - name: Log V version | |
| run: v version | |
| - name: Install native dependencies | |
| run: | | |
| v retry -- sudo apt -qq update | |
| v retry -- sudo apt install -y \ | |
| build-essential \ | |
| pkg-config \ | |
| libfreetype-dev \ | |
| libharfbuzz-dev \ | |
| libfribidi-dev \ | |
| libfontconfig1-dev \ | |
| libpango1.0-dev \ | |
| libgl1-mesa-dev \ | |
| libxcursor-dev \ | |
| libxi-dev \ | |
| libxrandr-dev \ | |
| libxinerama-dev \ | |
| libasound2-dev \ | |
| fonts-noto \ | |
| fonts-noto-color-emoji \ | |
| xvfb | |
| - name: Verify native pkg-config modules | |
| run: pkg-config --exists $CORE_PKG_CONFIG_MODULES | |
| - name: Verify formatting | |
| run: | | |
| fmt_files=() | |
| while IFS= read -r file; do | |
| fmt_files+=("$file") | |
| done < <(git ls-files '*.v' '*.vsh' | sort) | |
| if [ "${#fmt_files[@]}" -eq 0 ]; then | |
| echo "No tracked V files found" | |
| exit 1 | |
| fi | |
| v fmt -verify -inprocess "${fmt_files[@]}" | |
| - name: Verify markdown | |
| run: | | |
| rm -rf "$RUNNER_TEMP/vglyph-vmodules-docs" | |
| mkdir -p "$RUNNER_TEMP/vglyph-vmodules-docs" | |
| ln -s "$PWD" "$RUNNER_TEMP/vglyph-vmodules-docs/vglyph" | |
| VMODULES="$RUNNER_TEMP/vglyph-vmodules-docs" v check-md README.md docs | |
| - name: Run tests | |
| run: | | |
| test_files=() | |
| while IFS= read -r file; do | |
| test_files+=("$file") | |
| done < <(git ls-files '*_test.v' | grep -E '^[^/]+_test\.v$' | sort || true) | |
| if [ "${#test_files[@]}" -eq 0 ]; then | |
| echo "No tracked test files found" | |
| exit 1 | |
| fi | |
| echo "Test files: ${#test_files[@]}" | |
| test_index=1 | |
| for file in "${test_files[@]}"; do | |
| echo "[$test_index/${#test_files[@]}] $file" | |
| test_index=$((test_index + 1)) | |
| done | |
| VJOBS=1 v -no-parallel test "${test_files[@]}" | |
| - name: Compile examples | |
| run: | | |
| set -euo pipefail | |
| example_files=() | |
| while IFS= read -r file; do | |
| example_files+=("$file") | |
| done < <(git ls-files 'examples/*.v' | grep -E '^examples/[^/]+\.v$' | sort || true) | |
| if [ "${#example_files[@]}" -eq 0 ]; then | |
| echo "No tracked examples found" | |
| exit 1 | |
| fi | |
| rm -rf "$RUNNER_TEMP/vglyph-vmodules" "$RUNNER_TEMP/vglyph-example-bin" | |
| mkdir -p "$RUNNER_TEMP/vglyph-vmodules" "$RUNNER_TEMP/vglyph-example-bin" | |
| ln -s "$PWD" "$RUNNER_TEMP/vglyph-vmodules/vglyph" | |
| echo "Examples: ${#example_files[@]}" | |
| example_index=1 | |
| for file in "${example_files[@]}"; do | |
| echo "[$example_index/${#example_files[@]}] $file" | |
| VMODULES="$RUNNER_TEMP/vglyph-vmodules" \ | |
| v -no-parallel -path "@vlib|@vmodules|." \ | |
| -o "$RUNNER_TEMP/vglyph-example-bin/$(basename "${file%.v}")" \ | |
| "$file" | |
| example_index=$((example_index + 1)) | |
| done | |
| macos: | |
| name: CI Checks / macOS | |
| runs-on: macos-latest | |
| timeout-minutes: 70 | |
| env: | |
| VFLAGS: -no-parallel | |
| VJOBS: 1 | |
| steps: | |
| - name: Checkout vglyph | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Install V | |
| uses: vlang/setup-v@v1.4 | |
| with: | |
| check-latest: true | |
| - name: Log V version | |
| run: v version | |
| - name: Install native dependencies | |
| run: v retry -- brew install pkg-config pango freetype harfbuzz fribidi fontconfig | |
| - name: Verify native pkg-config modules | |
| run: pkg-config --exists $CORE_PKG_CONFIG_MODULES | |
| - name: Run tests | |
| run: | | |
| test_files=() | |
| while IFS= read -r file; do | |
| test_files+=("$file") | |
| done < <(git ls-files '*_test.v' | grep -E '^[^/]+_test\.v$' | sort || true) | |
| if [ "${#test_files[@]}" -eq 0 ]; then | |
| echo "No tracked test files found" | |
| exit 1 | |
| fi | |
| echo "Test files: ${#test_files[@]}" | |
| test_index=1 | |
| for file in "${test_files[@]}"; do | |
| echo "[$test_index/${#test_files[@]}] $file" | |
| test_index=$((test_index + 1)) | |
| done | |
| VJOBS=1 v -no-parallel test "${test_files[@]}" | |
| - name: Compile examples | |
| run: | | |
| set -euo pipefail | |
| example_files=() | |
| while IFS= read -r file; do | |
| example_files+=("$file") | |
| done < <(git ls-files 'examples/*.v' | grep -E '^examples/[^/]+\.v$' | sort || true) | |
| if [ "${#example_files[@]}" -eq 0 ]; then | |
| echo "No tracked examples found" | |
| exit 1 | |
| fi | |
| rm -rf "$RUNNER_TEMP/vglyph-vmodules" "$RUNNER_TEMP/vglyph-example-bin" | |
| mkdir -p "$RUNNER_TEMP/vglyph-vmodules" "$RUNNER_TEMP/vglyph-example-bin" | |
| ln -s "$PWD" "$RUNNER_TEMP/vglyph-vmodules/vglyph" | |
| echo "Examples: ${#example_files[@]}" | |
| example_index=1 | |
| for file in "${example_files[@]}"; do | |
| echo "[$example_index/${#example_files[@]}] $file" | |
| VMODULES="$RUNNER_TEMP/vglyph-vmodules" \ | |
| v -no-parallel -path "@vlib|@vmodules|." \ | |
| -o "$RUNNER_TEMP/vglyph-example-bin/$(basename "${file%.v}")" \ | |
| "$file" | |
| example_index=$((example_index + 1)) | |
| done | |
| windows: | |
| name: CI Checks / Windows | |
| runs-on: windows-latest | |
| timeout-minutes: 70 | |
| env: | |
| VFLAGS: -no-parallel | |
| VJOBS: 1 | |
| VCPKG_BINARY_CACHE: ${{ github.workspace }}\vcpkg-binary-cache | |
| VCPKG_BINARY_SOURCES: clear;files,${{ github.workspace }}\vcpkg-binary-cache,readwrite | |
| steps: | |
| - name: Checkout vglyph | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Resolve V revision | |
| id: v | |
| shell: pwsh | |
| run: | | |
| $ErrorActionPreference = 'Stop' | |
| $revision = (git ls-remote https://github.com/vlang/v HEAD).Split()[0] | |
| "revision=$revision" | Add-Content -Path $env:GITHUB_OUTPUT | |
| - name: Restore V compiler cache | |
| id: restore-v-cache | |
| uses: actions/cache/restore@v4 | |
| with: | |
| path: ${{ runner.temp }}\v | |
| key: windows-v-compiler-${{ steps.v.outputs.revision }}-v1 | |
| - name: Install V | |
| shell: pwsh | |
| run: | | |
| $ErrorActionPreference = 'Stop' | |
| function Assert-NativeCommand($Message) { | |
| if ($LASTEXITCODE -ne 0) { | |
| throw $Message | |
| } | |
| } | |
| $expectedRevision = '${{ steps.v.outputs.revision }}' | |
| $vCheckout = Join-Path $env:RUNNER_TEMP 'v' | |
| if (Test-Path (Join-Path $vCheckout 'v.exe')) { | |
| $cachedRevision = (& git -C $vCheckout rev-parse HEAD).Trim() | |
| Assert-NativeCommand "Could not inspect cached V revision" | |
| if ($cachedRevision -ne $expectedRevision) { | |
| Write-Host "Cached V revision $cachedRevision does not match expected $expectedRevision; rebuilding." | |
| Remove-Item -Recurse -Force $vCheckout | |
| } | |
| } | |
| if (-not (Test-Path (Join-Path $vCheckout 'v.exe'))) { | |
| if (Test-Path $vCheckout) { | |
| Remove-Item -Recurse -Force $vCheckout | |
| } | |
| git init $vCheckout | |
| Assert-NativeCommand "git init failed" | |
| git -C $vCheckout remote add origin https://github.com/vlang/v | |
| Assert-NativeCommand "git remote add failed" | |
| git -C $vCheckout fetch --depth 1 origin $expectedRevision | |
| Assert-NativeCommand "git fetch failed" | |
| git -C $vCheckout checkout --detach FETCH_HEAD | |
| Assert-NativeCommand "git checkout failed" | |
| Push-Location $vCheckout | |
| cmd /c makev.bat | |
| if ($LASTEXITCODE -ne 0) { | |
| throw "makev.bat failed" | |
| } | |
| Pop-Location | |
| } | |
| $vPath = (Resolve-Path $vCheckout).Path | |
| Add-Content -Path $env:GITHUB_PATH -Value $vPath | |
| - name: Log V version | |
| shell: pwsh | |
| run: v version | |
| - name: Save V compiler cache | |
| if: steps.restore-v-cache.outputs.cache-hit != 'true' | |
| uses: actions/cache/save@v4 | |
| with: | |
| path: ${{ runner.temp }}\v | |
| key: ${{ steps.restore-v-cache.outputs.cache-primary-key }} | |
| - name: Restore vcpkg binary cache | |
| id: restore-vcpkg-cache | |
| uses: actions/cache/restore@v4 | |
| with: | |
| path: ${{ env.VCPKG_BINARY_CACHE }} | |
| key: windows-vcpkg-x64-windows-vglyph-native-${{ steps.v.outputs.revision }}-v1 | |
| restore-keys: | | |
| windows-vcpkg-x64-windows-vglyph-native- | |
| - name: Install native dependencies | |
| shell: pwsh | |
| run: | | |
| $ErrorActionPreference = 'Stop' | |
| New-Item -ItemType Directory -Force -Path "$env:VCPKG_BINARY_CACHE" | Out-Null | |
| vcpkg install pango freetype harfbuzz fribidi fontconfig --triplet x64-windows | |
| - name: Save vcpkg binary cache | |
| if: steps.restore-vcpkg-cache.outputs.cache-hit != 'true' | |
| uses: actions/cache/save@v4 | |
| with: | |
| path: ${{ env.VCPKG_BINARY_CACHE }} | |
| key: ${{ steps.restore-vcpkg-cache.outputs.cache-primary-key }} | |
| - name: Expose pkg-config paths | |
| shell: pwsh | |
| run: | | |
| $ErrorActionPreference = 'Stop' | |
| $triplet = 'x64-windows' | |
| $vcpkgExe = (Get-Command vcpkg -ErrorAction Stop).Source | |
| $roots = @() | |
| if ($vcpkgExe) { | |
| $roots += Split-Path -Parent $vcpkgExe | |
| } | |
| if ($env:VCPKG_ROOT) { | |
| $roots += $env:VCPKG_ROOT | |
| } | |
| $vcpkgRoot = $null | |
| foreach ($root in ($roots | Select-Object -Unique)) { | |
| if (Test-Path (Join-Path $root "installed\$triplet")) { | |
| $vcpkgRoot = $root | |
| break | |
| } | |
| } | |
| if (-not $vcpkgRoot) { | |
| throw "Could not find vcpkg installed\$triplet from vcpkg.exe or VCPKG_ROOT" | |
| } | |
| $tripletRoot = Join-Path $vcpkgRoot "installed\$triplet" | |
| $pkgConfigDirs = @( | |
| (Join-Path $tripletRoot 'lib\pkgconfig'), | |
| (Join-Path $tripletRoot 'share\pkgconfig') | |
| ) | Where-Object { Test-Path $_ } | |
| if ($pkgConfigDirs.Count -eq 0) { | |
| throw "No pkgconfig directories found under $tripletRoot" | |
| } | |
| $pkgConfigPath = $pkgConfigDirs -join ';' | |
| "PKG_CONFIG_PATH=$pkgConfigPath" | Add-Content -Path $env:GITHUB_ENV | |
| $env:PKG_CONFIG_PATH = $pkgConfigPath | |
| $pathEntries = @() | |
| $binDir = Join-Path $tripletRoot 'bin' | |
| if (Test-Path $binDir) { | |
| $pathEntries += $binDir | |
| } | |
| $pkgconfDir = Join-Path $tripletRoot 'tools\pkgconf' | |
| if (Test-Path $pkgconfDir) { | |
| $pathEntries += $pkgconfDir | |
| } | |
| foreach ($entry in $pathEntries) { | |
| $entry | Add-Content -Path $env:GITHUB_PATH | |
| } | |
| if ($pathEntries.Count -gt 0) { | |
| $env:PATH = ($pathEntries + $env:PATH) -join ';' | |
| } | |
| if (-not (Get-Command pkg-config -ErrorAction SilentlyContinue)) { | |
| $pkgconf = Get-Command pkgconf -ErrorAction SilentlyContinue | |
| if ($pkgconf) { | |
| $shimDir = Join-Path $env:RUNNER_TEMP 'pkg-config-shim' | |
| New-Item -ItemType Directory -Force -Path $shimDir | Out-Null | |
| Set-Content -Path (Join-Path $shimDir 'pkg-config.cmd') -Encoding ascii -Value @( | |
| '@echo off', | |
| '"' + $pkgconf.Source + '" %*' | |
| ) | |
| $shimDir | Add-Content -Path $env:GITHUB_PATH | |
| $env:PATH = "$shimDir;$env:PATH" | |
| } | |
| } | |
| - name: Configure MSVC developer environment | |
| uses: ilammy/msvc-dev-cmd@v1 | |
| - name: Verify native pkg-config modules | |
| shell: pwsh | |
| run: | | |
| $ErrorActionPreference = 'Stop' | |
| $modules = '${{ env.CORE_PKG_CONFIG_MODULES }}'.Split(' ') | |
| pkg-config --exists @modules | |
| if ($LASTEXITCODE -ne 0) { | |
| throw "pkg-config could not resolve: ${{ env.CORE_PKG_CONFIG_MODULES }}" | |
| } | |
| - name: Run tests | |
| shell: pwsh | |
| run: | | |
| [string[]]$testFiles = @(git ls-files | Where-Object { $_ -match '^[^/]+_test\.v$' } | Sort-Object) | |
| if ($testFiles.Length -eq 0) { | |
| throw "No tracked test files found" | |
| } | |
| $totalTests = $testFiles.Length | |
| Write-Host "Test files: $totalTests" | |
| for ($i = 0; $i -lt $totalTests; $i++) { | |
| Write-Host "[$($i + 1)/$totalTests] $($testFiles[$i])" | |
| } | |
| $env:VJOBS = '1' | |
| v -no-parallel -cc msvc test @testFiles | |
| if ($LASTEXITCODE -ne 0) { | |
| exit $LASTEXITCODE | |
| } | |
| - name: Compile examples | |
| shell: pwsh | |
| run: | | |
| $ErrorActionPreference = 'Stop' | |
| $vmodules = Join-Path $env:RUNNER_TEMP 'vglyph-vmodules' | |
| $outDir = Join-Path $env:RUNNER_TEMP 'vglyph-example-bin' | |
| Remove-Item -Recurse -Force $vmodules, $outDir -ErrorAction SilentlyContinue | |
| New-Item -ItemType Directory -Force -Path $vmodules, $outDir | Out-Null | |
| New-Item -ItemType Junction -Path (Join-Path $vmodules 'vglyph') -Target $env:GITHUB_WORKSPACE | Out-Null | |
| $env:VMODULES = $vmodules | |
| [string[]]$exampleFiles = @(git ls-files | Where-Object { $_ -match '^examples/[^/]+\.v$' } | Sort-Object) | |
| if ($exampleFiles.Length -eq 0) { | |
| throw "No tracked examples found" | |
| } | |
| $totalExamples = $exampleFiles.Length | |
| Write-Host "Examples: $totalExamples" | |
| for ($i = 0; $i -lt $totalExamples; $i++) { | |
| $file = $exampleFiles[$i] | |
| Write-Host "[$($i + 1)/$totalExamples] $file" | |
| $out = Join-Path $outDir ([System.IO.Path]::GetFileNameWithoutExtension($file)) | |
| v -no-parallel -cc msvc -path '@vlib|@vmodules|.' -o $out $file | |
| if ($LASTEXITCODE -ne 0) { | |
| throw "example failed: $file" | |
| } | |
| } |