Browse Source

Add GitHub Actions for Building and Running Tests (#45)

This commit adds supports for building and running tests via GitHub actions.
Artem V. Ageev 11 months ago
parent
commit
9c951c636f

+ 7 - 0
.github/dependabot.yml

@@ -0,0 +1,7 @@
+---
+version: 2
+updates:
+  - package-ecosystem: "github-actions"
+    directory: "/"
+    schedule:
+      interval: "monthly"

+ 7 - 0
.github/workflows/make.json

@@ -0,0 +1,7 @@
+{
+    "app" : "CryptoLib.Samples",
+    "lib" : "CryptoLib",
+    "tst" : "CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.Tests.lpi",
+    "pkg" : [
+    ]
+}

+ 187 - 0
.github/workflows/make.ps1

@@ -0,0 +1,187 @@
+#!/usr/bin/env pwsh
+##############################################################################################################
+
+Function Show-Usage {
+    "
+vagrant  = 'it-gro/win10-ltsc-eval'
+download = 'https://microsoft.com/en-us/evalcenter'
+package  = 'https://learn.microsoft.com/en-us/mem/configmgr/develop/apps/how-to-create-the-windows-installer-file-msi'
+shell    = 'https://learn.microsoft.com/en-us/powershell'
+
+Usage: pwsh -File $($PSCommandPath) [OPTIONS]
+Options:
+    build
+    lint
+" | Out-Host
+}
+
+Function Build-Project {
+    New-Variable -Option Constant -Name VAR -Value (Get-Content -Path $PSCommandPath.Replace('ps1', 'json') | ConvertFrom-Json)
+    If (! (Test-Path -Path $Var.app)) {
+        "$([char]27)[31m.... $($Var.app) did not find!$([char]27)[0m" | Out-Host
+        Exit 1
+    }
+    If (Test-Path -Path '.gitmodules') {
+        & git submodule update --init --recursive --force --remote | Out-Host
+        "$([char]27)[33m.... [[$($LastExitCode)]] git submodule update$([char]27)[0m" | Out-Host
+    }
+    @(
+        @{
+            Cmd = 'lazbuild'
+            Url = 'https://fossies.org/windows/misc/lazarus-3.6-fpc-3.2.2-win64.exe'
+            Path = "C:\Lazarus"
+        }
+    ) | Where-Object {
+        ! (Test-Path -Path $_.Path)
+    } | ForEach-Object {
+        $_.Url | Request-File | Install-Program
+        $Env:PATH+=";$($_.Path)"
+        Return (Get-Command $_.Cmd).Source
+    } | Out-Host
+    $VAR.Pkg | ForEach-Object {
+        @{
+            Name = $_
+            Uri = "https://packages.lazarus-ide.org/$($_).zip"
+            Path = "$($Env:HOME)\.lazarus\onlinepackagemanager\packages\$($_)"
+            OutFile = (New-TemporaryFile).FullName
+        }
+    } | Where-Object {
+        ! (Test-Path -Path $_.Path) &&
+        ! (& lazbuild --verbose-pkgsearch $_.Name ) &&
+        ! (& lazbuild --add-package $_.Name)
+    } | ForEach-Object -Parallel {
+        Invoke-WebRequest -OutFile $_.OutFile -Uri $_.Uri
+        New-Item -Type Directory -Path $_.Path | Out-Null
+        Expand-Archive -Path $_.OutFile -DestinationPath $_.Path
+        Remove-Item $_.OutFile
+        (Get-ChildItem -Filter '*.lpk' -Recurse -File –Path $_.Path).FullName |
+            ForEach-Object {
+                & lazbuild --add-package-link $_ | Out-Null
+                Return "$([char]27)[33m.... [$($LastExitCode)] add package link $($_)$([char]27)[0m"
+            }
+    } | Out-Host
+    If (Test-Path -Path $VAR.lib) {
+        (Get-ChildItem -Filter '*.lpk' -Recurse -File –Path $VAR.lib).FullName |
+            ForEach-Object {
+                & lazbuild --add-package-link $_ | Out-Null
+                Return "$([char]27)[33m.... [$($LastExitCode)] add package link $($_)$([char]27)[0m"
+            } | Out-Host
+    }
+    Exit $(Switch (Test-Path -Path $Var.tst) {
+        true {
+            $Output = (
+                & lazbuild --build-all --recursive --no-write-project $VAR.tst |
+                    Where-Object {
+                        $_.Contains('Linking')
+                    } | ForEach-Object {
+                        $_.Split(' ')[2].Replace('bin', 'bin\.')
+                    }
+            )
+            $Output = (& $Output --all --format=plain --progress)
+            $exitCode = Switch ($LastExitCode) {
+                0 {0}
+                Default {
+                    1
+                }
+            }
+            $Output | Out-Host
+            Return $exitCode
+K        }
+        Default {0}
+    }) + (
+        (Get-ChildItem -Filter '*.lpi' -Recurse -File –Path $Var.app).FullName |
+            ForEach-Object {
+                $Output = (& lazbuild --build-all --recursive --no-write-project $_)
+                $Result = @("$([char]27)[32m.... [$($LastExitCode)] build project $($_)$([char]27)[0m")
+                $exitCode = $(Switch ($LastExitCode) {
+                    0 {
+                        $Result += $Output | Select-String -Pattern 'Linking'
+                        0
+                    }
+                    Default {
+                        $Result += $Output | Select-String -Pattern 'Error:', 'Fatal:'
+                        1
+                    }
+                })
+                $Result | Out-Host
+                Return $exitCode
+            } | Measure-Object -Sum
+    ).Sum
+}
+
+Function Request-File {
+    While ($Input.MoveNext()) {
+        New-Variable -Option Constant -Name VAR -Value @{
+            Uri = $Input.Current
+            OutFile = (Split-Path -Path $Input.Current -Leaf).Split('?')[0]
+        }
+        Invoke-WebRequest @VAR
+        Return $VAR.OutFile
+    }
+}
+
+Function Install-Program {
+    While ($Input.MoveNext()) {
+        Switch ((Split-Path -Path $Input.Current -Leaf).Split('.')[-1]) {
+            'msi' {
+                & msiexec /passive /package $Input.Current | Out-Null
+            }
+            Default {
+                & ".\$($Input.Current)" /SP- /VERYSILENT /SUPPRESSMSGBOXES /NORESTART | Out-Null
+            }
+        }
+        Remove-Item $Input.Current
+    }
+}
+
+Function Request-URL([Switch] $Post) {
+    $VAR = Switch ($Post) {
+        true {
+            @{
+                Method = 'POST'
+                Headers = @{
+                    ContentType = 'application/json'
+                }
+                Uri = 'https://postman-echo.com/post'
+                Body = @{
+                    One = '1'
+                } | ConvertTo-Json
+            }
+        }
+        false {
+            @{
+                Uri = 'https://postman-echo.com/get'
+            }
+        }
+    }
+    Return (Invoke-WebRequest @VAR | ConvertFrom-Json).Headers
+}
+
+Function Switch-Action {
+    $ErrorActionPreference = 'stop'
+    Set-PSDebug -Strict #-Trace 1
+    Invoke-ScriptAnalyzer -EnableExit -Path $PSCommandPath
+    If ($args.count -gt 0) {
+        Switch ($args[0]) {
+            'lint' {
+                Invoke-ScriptAnalyzer -EnableExit -Recurse -Path '.'
+                (Get-ChildItem -Filter '*.ps1' -Recurse -Path '.').FullName |
+                    ForEach-Object {
+                        Invoke-Formatter -ScriptDefinition $(Get-Content -Path $_ | Out-String) |
+                            Set-Content -Path $_
+                    }
+            }
+            'build' {
+                Build-Project
+            }
+            Default {
+                Show-Usage
+            }
+        }
+    } Else {
+        Show-Usage
+    }
+}
+
+##############################################################################################################
+Switch-Action @args

+ 112 - 0
.github/workflows/make.sh

@@ -0,0 +1,112 @@
+#!/usr/bin/env bash
+##############################################################################################################
+
+function priv_clippit
+(
+    cat <<EOF
+https://google.github.io/styleguide/shellguide.html
+https://guide.bash.academy
+https://devhints.io/bash
+https://tldr.sh
+
+Usage: bash ${0} [OPTIONS]
+Options:
+    build   Build program
+EOF
+)
+
+function priv_lazbuild
+(
+    mapfile -t < "${0//sh/json}"
+    declare -rA VAR=(
+        [app]=$(jq --raw-output --exit-status '.app' <<< "${MAPFILE[@]}")
+        [lib]=$(jq --raw-output --exit-status '.lib' <<< "${MAPFILE[@]}")
+        [tst]=$(jq --raw-output --exit-status '.tst' <<< "${MAPFILE[@]}")
+        [opt]=$(jq --raw-output --exit-status '.opt' <<< "${MAPFILE[@]}")
+    )
+    if ! [[ -d "${VAR[app]}" ]]; then
+        printf '\x1b[32m\t[%s] did not find!\x1b[0m\n' "${VAR[app]}"
+        exit 1
+    fi >&2
+    if [[ -f '.gitmodules' ]]; then
+        git submodule update --init --recursive --force --remote &
+    fi
+    if ! (command -v lazbuild); then
+        # shellcheck source=/dev/null
+        source '/etc/os-release'
+        case ${ID:?} in
+            debian | ubuntu)
+                sudo apt-get update
+                sudo apt-get install -y lazarus{-ide-qt5,} &
+                ;;
+        esac
+    fi &>/dev/null
+    wait
+    while read -r; do
+        (
+            declare -rA TMP=(
+                [url]="https://packages.lazarus-ide.org/${REPLY}.zip"
+                [dir]="${HOME}/.lazarus/onlinepackagemanager/packages/${REPLY}"
+                [out]=$(mktemp)
+            )
+            if ! [[ -d "${TMP[dir]}" ]] &&
+               ! (lazbuild --verbose-pkgsearch "${REPLY}") &&
+               ! (lazbuild --add-package "${REPLY}"); then
+                    wget --quiet --output-document "${TMP[out]}" "${TMP[url]}"
+                    mkdir --parents "${TMP[dir]}"
+                    unzip -o "${TMP[out]}" -d "${TMP[dir]}"
+                    rm --verbose "${TMP[out]}"
+                    find "${TMP[dir]}" -type 'f' -name '*.lpk' -printf '\033[33m\tadd package link\t%p\033[0m\n' -exec \
+                        lazbuild --add-package-link {} + >&2
+            fi
+        ) &
+    done < <(jq --raw-output --exit-status '.pkg[]' <<< "${MAPFILE[@]}")
+    wait
+    if [[ -d "${VAR[lib]}" ]]; then
+        find "${VAR[lib]}" -type 'f' -name '*.lpk' -printf '\033[33m\tadd package link\t%p\033[0m\n' -exec \
+            lazbuild --add-package-link {} + >&2
+    fi
+    declare -i exitCode=0
+    if [[ -f "${VAR[tst]}" ]]; then
+        declare -A TMP=(
+            [tst]=$(
+                lazbuild --build-all --recursive --no-write-project "${VAR[tst]}" |
+                    awk '/Linking/{print $3}'
+            )
+        )
+        if ! ("${TMP[tst]}" --all --format=plain --progress >&2); then
+            ((exitCode+=1))
+        fi
+    fi
+    while read -r; do
+        declare -A TMP=(
+            [out]=$(mktemp)
+        )
+        if (lazbuild --build-all --recursive --no-write-project "${REPLY}" > "${TMP[out]}"); then
+            printf '\x1b[32m\t[%s]\t%s\x1b[0m\n' "${?}" "${REPLY}"
+            grep --color='always' 'Linking' "${TMP[out]}"
+        else
+            printf '\x1b[31m\t[%s]\t%s\x1b[0m\n' "${?}" "${REPLY}"
+            grep --color='always' --extended-regexp '(Error|Fatal):' "${TMP[out]}"
+            ((exitCode+=1))
+        fi >&2
+        rm "${TMP[out]}"
+    done < <(find "${VAR[app]}" -type 'f' -name '*.lpi')
+    exit "${exitCode}"
+)
+
+function priv_main
+(
+    set -euo pipefail
+    if ((${#})); then
+        case ${1} in
+            build) priv_lazbuild ;;
+            *) priv_clippit ;;
+        esac
+    else
+        priv_clippit
+    fi
+)
+
+##############################################################################################################
+priv_main "${@}" >/dev/null

+ 49 - 0
.github/workflows/make.yml

@@ -0,0 +1,49 @@
+---
+name: Make
+
+on:
+  schedule:
+    - cron:  '0 0 1 * *'
+  push:
+    branches:
+      - "**"
+  pull_request:
+    branches:
+      - master
+      - main
+
+concurrency:
+  group: ${{ github.workflow }}-${{ github.ref }}
+  cancel-in-progress: true
+
+jobs:
+  build:
+    runs-on: ${{ matrix.os }}
+    timeout-minutes: 120
+    strategy:
+      matrix:
+        os:
+          - ubuntu-latest
+          - windows-latest
+    steps:
+    - name: Checkout
+      uses: actions/checkout@v4
+      with:
+        submodules: true
+
+    - name: Build on Linux
+      if: runner.os == 'Linux'
+      shell: bash
+      run: bash .github/workflows/make.sh build
+
+    - name: Build on Windows
+      if: runner.os == 'Windows'
+      shell: powershell
+      run: pwsh -File .github/workflows/make.ps1 build
+
+    - name: Archive
+      if: runner.os == 'Windows'
+      uses: actions/upload-artifact@v4
+      with:
+        retention-days: 1
+        path: src\bin\*.exe

+ 6 - 0
.gitmodules

@@ -0,0 +1,6 @@
+[submodule "CryptoLib/HashLib4Pascal"]
+	path = CryptoLib/HashLib4Pascal
+	url = [email protected]:Xor-el/HashLib4Pascal.git
+[submodule "CryptoLib/SimpleBaseLib4Pascal"]
+	path = CryptoLib/SimpleBaseLib4Pascal
+	url = [email protected]:Xor-el/SimpleBaseLib4Pascal.git

+ 1 - 0
CryptoLib/HashLib4Pascal

@@ -0,0 +1 @@
+Subproject commit b634088b9efc244d31c20b7004fe6ef342cd717f

+ 1 - 0
CryptoLib/SimpleBaseLib4Pascal

@@ -0,0 +1 @@
+Subproject commit ae402fee0b6d5c6e25d6f484e5ca9f3ee64629e8