Build #482
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: Build | |
| on: | |
| pull_request: | |
| paths: | |
| - .github/workflows/build.yml | |
| - service/** | |
| push: | |
| branches: | |
| - main | |
| tags-ignore: | |
| - "**" | |
| paths: | |
| - .github/workflows/build.yml | |
| - service/** | |
| workflow_dispatch: | |
| inputs: | |
| sign: | |
| description: Sign binaries | |
| type: choice | |
| options: | |
| - 'no' | |
| - test | |
| - production | |
| default: test | |
| cldr-version: | |
| description: CLDR Version | |
| type: string | |
| required: false | |
| iconv-version: | |
| description: Iconv Version | |
| type: string | |
| required: false | |
| curl-version: | |
| description: Curl Version | |
| type: string | |
| required: false | |
| json-c-version: | |
| description: JSON-C Version | |
| type: string | |
| required: false | |
| gettext-version: | |
| description: Gettext Version | |
| type: string | |
| required: false | |
| publish-release: | |
| description: Publish release after build | |
| type: boolean | |
| required: false | |
| permissions: | |
| contents: write | |
| jobs: | |
| test-bash-scripts: | |
| name: Test bash scripts | |
| runs-on: ubuntu-latest | |
| container: | |
| image: mvdan/shfmt:v3.12.0-alpine | |
| options: --entrypoint /bin/sh | |
| steps: | |
| - | |
| name: Checkout | |
| uses: actions/checkout@v6 | |
| - | |
| name: Check scripts | |
| run: | | |
| files="$(shfmt --find .)" | |
| if [ $? -ne 0 ] || [ -z "$files" ]; then | |
| echo 'Failed to list shell scripts' | |
| exit 1 | |
| fi | |
| rc=0 | |
| for file in $files; do | |
| printf '# %s... ' "$file" | |
| if shfmt --diff --simplify --indent 4 --case-indent --func-next-line -- "$file"; then | |
| echo 'ok.' | |
| else | |
| rc=1 | |
| printf '\n\n' | |
| fi | |
| done | |
| exit $rc | |
| test-pwsh-scripts: | |
| name: Test PowerShell scripts | |
| runs-on: windows-latest | |
| env: | |
| PSScriptAnalyzerVersion: 1.24.0 | |
| steps: | |
| - | |
| name: Checkout | |
| uses: actions/checkout@v6 | |
| - | |
| name: Create directory structure | |
| run: | | |
| New-Item -ItemType Directory -Force -ErrorAction Stop -Path @( | |
| 'downloads' | |
| 'tmp' | |
| ) | Out-Null | |
| - | |
| name: Restore cache | |
| id: restore-cache | |
| uses: actions/cache/restore@v5 | |
| with: | |
| key: test-pwsh-scripts | |
| path: downloads | |
| - | |
| name: Download PSScriptAnalyzer module | |
| run: > | |
| ./service/download-archive.ps1 | |
| -Url "https://www.powershellgallery.com/api/v2/package/PSScriptAnalyzer/${env:PSScriptAnalyzerVersion}" | |
| -LocalFilePath "downloads\psscriptanalyzer.${env:PSScriptAnalyzerVersion}.nupkg" | |
| - | |
| name: Extract PSScriptAnalyzer | |
| working-directory: tmp | |
| run: Expand-Archive -Path "..\downloads\psscriptanalyzer.${env:PSScriptAnalyzerVersion}.nupkg" -DestinationPath .\PSScriptAnalyzer | |
| - | |
| name: Import PSScriptAnalyzer module | |
| working-directory: tmp | |
| run: Import-Module -Name .\PSScriptAnalyzer\ -Force | |
| - | |
| name: Check scripts | |
| run: | | |
| $rc = 0 | |
| $files = Get-ChildItem -Path . -Recurse -File -Filter *.ps1 | |
| foreach ($file in $files) { | |
| Write-Host -Object "# $($file.Name)... " -NoNewline | |
| $records = Invoke-ScriptAnalyzer -Path $file -ExcludeRule PSAvoidUsingWriteHost,PSUseShouldProcessForStateChangingFunctions,PSUseSingularNouns | |
| if (-not($records)) { | |
| Write-Host -Object 'ok.' | |
| } else { | |
| $rc = 1 | |
| Write-Host -Object 'ERRORS!' | |
| foreach ($record in $records) { | |
| Write-Host -Object " - line $($record.Line): $($record.RuleName))`n $($record.Message)`n" | |
| } | |
| Write-Host -Object '' | |
| } | |
| } | |
| exit $rc | |
| - | |
| name: Persist cache | |
| if: always() && steps.restore-cache.outputs.cache-hit != 'true' | |
| uses: actions/cache/save@v5 | |
| with: | |
| key: ${{ steps.restore-cache.outputs.cache-primary-key }} | |
| path: downloads | |
| versions: | |
| name: Resolve versions | |
| outputs: | |
| cygwin-mirror: ${{ steps.resolve.outputs.cygwin-mirror }} | |
| cldr-version: ${{ steps.resolve.outputs.cldr-version }} | |
| iconv-version: ${{ steps.resolve.outputs.iconv-version }} | |
| iconv-version-base: ${{ steps.resolve.outputs.iconv-version-base }} | |
| iconv-tarball-from-commit: ${{ steps.resolve.outputs.iconv-tarball-from-commit }} | |
| iconv-source-url: ${{ steps.resolve.outputs.iconv-source-url }} | |
| curl-version-default: ${{ steps.resolve.outputs.curl-version }} | |
| json-c-version-default: ${{ steps.resolve.outputs.json-c-version }} | |
| gettext-version: ${{ steps.resolve.outputs.gettext-version }} | |
| gettext-source-url: ${{ steps.resolve.outputs.gettext-source-url }} | |
| signpath-signing-policy-default: ${{ steps.resolve.outputs.signpath-signing-policy }} | |
| signpath-artifactconfiguration-files: ${{ steps.resolve.outputs.signpath-artifactconfiguration-files }} | |
| signatures-canbeinvalid: ${{ steps.resolve.outputs.signatures-canbeinvalid }} | |
| release-tag: ${{ steps.resolve.outputs.release-tag }} | |
| is-prerelease: ${{ steps.resolve.outputs.is-prerelease }} | |
| runs-on: windows-2022 | |
| steps: | |
| - | |
| name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: ${{ github.event_name == 'pull_request' && '0' || '1' }} | |
| - | |
| name: Resolve | |
| id: resolve | |
| shell: pwsh | |
| run: > | |
| ./service/resolve-versions.ps1 | |
| -CLDRVersion '${{ github.event.inputs.cldr-version }}' | |
| -IconvVersion '${{ github.event.inputs.iconv-version }}' | |
| -CurlVersion '${{ github.event.inputs.curl-version }}' | |
| -JsonCVersion '${{ github.event.inputs.json-c-version }}' | |
| -GettextVersion '${{ github.event.inputs.gettext-version }}' | |
| -Sign '${{ github.event.inputs.sign }}' | |
| -PublishRelease ${{ github.event.inputs.publish-release == 'true' && '$true' || '$false' }} | |
| build-iconv-tarball: | |
| name: Build iconv tarball | |
| needs: | |
| - versions | |
| outputs: | |
| artifact-id: ${{ steps.upload.outputs.artifact-id }} | |
| runs-on: ubuntu-latest | |
| container: | |
| image: debian:trixie | |
| steps: | |
| - | |
| name: Create directory structure | |
| if: needs.versions.outputs.iconv-tarball-from-commit | |
| run: mkdir output | |
| - | |
| name: Restore cache | |
| if: needs.versions.outputs.iconv-tarball-from-commit | |
| id: restore-cache | |
| uses: actions/cache/restore@v5 | |
| with: | |
| key: build-iconv-${{ needs.versions.outputs.iconv-tarball-from-commit }} | |
| path: output | |
| - | |
| name: Check tarball existence | |
| if: needs.versions.outputs.iconv-tarball-from-commit | |
| id: check-tarball | |
| run: | | |
| if [ -f output/libiconv-${{ needs.versions.outputs.iconv-version }}.tar.gz ]; then | |
| echo 'Tarball already exists in cache.' | |
| echo 'build=no' >>"$GITHUB_OUTPUT" | |
| else | |
| echo 'Tarball not found in cache. Will build it.' | |
| echo 'build=yes' >>"$GITHUB_OUTPUT" | |
| fi | |
| - | |
| name: Update system | |
| if: steps.check-tarball.outputs.build == 'yes' | |
| run: | | |
| apt-get update -q | |
| apt-get upgrade -qy | |
| - | |
| name: Install system dependencies | |
| if: steps.check-tarball.outputs.build == 'yes' | |
| run: > | |
| apt-get install -qy --no-install-recommends | |
| ca-certificates git curl xz-utils make python3 patch autoconf gcc libc6-dev gperf groff gettext | |
| - | |
| name: Install automake | |
| if: steps.check-tarball.outputs.build == 'yes' | |
| working-directory: /tmp | |
| run: | | |
| curl -sSL https://ftp.gnu.org/gnu/automake/automake-1.18.1.tar.xz | tar -xJ | |
| cd automake-* | |
| ./configure | |
| make install | |
| - | |
| name: Download iconv source code | |
| if: steps.check-tarball.outputs.build == 'yes' | |
| run: git clone https://git.savannah.gnu.org/git/libiconv.git | |
| - | |
| name: Checkout commit ${{ needs.versions.outputs.iconv-tarball-from-commit }} | |
| if: steps.check-tarball.outputs.build == 'yes' | |
| working-directory: libiconv | |
| run: git checkout ${{ needs.versions.outputs.iconv-tarball-from-commit }} | |
| - | |
| name: Pull git dependencies | |
| if: steps.check-tarball.outputs.build == 'yes' | |
| working-directory: libiconv | |
| run: ./autopull.sh --one-time | |
| - | |
| name: Autogenerate build system | |
| if: steps.check-tarball.outputs.build == 'yes' | |
| working-directory: libiconv | |
| run: ./autogen.sh | |
| - | |
| name: Configure | |
| if: steps.check-tarball.outputs.build == 'yes' | |
| working-directory: libiconv | |
| run: ./configure | |
| - | |
| name: Build tarball | |
| if: steps.check-tarball.outputs.build == 'yes' | |
| working-directory: libiconv | |
| run: make dist VERSION=${{ needs.versions.outputs.iconv-version }} | |
| - | |
| name: Copy tarball to output | |
| if: steps.check-tarball.outputs.build == 'yes' | |
| run: cp libiconv/libiconv-${{ needs.versions.outputs.iconv-version }}.tar.gz output/ | |
| - | |
| name: Persist cache | |
| if: steps.check-tarball.outputs.build == 'yes' && steps.restore-cache.outputs.cache-hit != 'true' | |
| uses: actions/cache/save@v5 | |
| with: | |
| key: ${{ steps.restore-cache.outputs.cache-primary-key }} | |
| path: output | |
| - | |
| name: Upload tarball | |
| if: needs.versions.outputs.iconv-tarball-from-commit | |
| id: upload | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: tarball-iconv | |
| path: output/libiconv-${{ needs.versions.outputs.iconv-version }}.tar.gz | |
| if-no-files-found: error | |
| retention-days: 1 | |
| build: | |
| name: ${{ matrix.bits}}-bit ${{ matrix.link }} w/ ${{ matrix.compiler }} | |
| needs: | |
| - test-bash-scripts | |
| - test-pwsh-scripts | |
| - versions | |
| - build-iconv-tarball | |
| runs-on: windows-2022 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - bits: 32 | |
| link: shared | |
| compiler: gcc | |
| - bits: 32 | |
| link: static | |
| compiler: gcc | |
| - bits: 64 | |
| link: shared | |
| compiler: gcc | |
| - bits: 64 | |
| link: static | |
| compiler: gcc | |
| - bits: 32 | |
| link: shared | |
| compiler: msvc | |
| - bits: 32 | |
| link: static | |
| compiler: msvc | |
| - bits: 64 | |
| link: shared | |
| compiler: msvc | |
| - bits: 64 | |
| link: static | |
| compiler: msvc | |
| env: | |
| CYGWIN_NOWINPATH: 1 | |
| CHERE_INVOKING: 1 | |
| defaults: | |
| run: | |
| shell: D:\cygwin\bin\bash.exe --login -o igncr -o errexit -o pipefail {0} | |
| steps: | |
| - | |
| name: Configure git | |
| shell: cmd | |
| run: git config --global core.autocrlf input | |
| - | |
| name: Checkout | |
| uses: actions/checkout@v6 | |
| - | |
| name: Create directory structure | |
| shell: pwsh | |
| run: | | |
| New-Item -ItemType Directory -Force -ErrorAction Stop -Path @( | |
| 'src/downloads' | |
| 'installed/bin' | |
| 'installed/include' | |
| 'installed/lib' | |
| 'installed/licenses' | |
| 'output-exe' | |
| 'output-dev' | |
| 'assets' | |
| ) | Out-Null | |
| - | |
| name: Restore cache | |
| id: restore-cache | |
| uses: actions/cache/restore@v5 | |
| with: | |
| key: build-${{ matrix.link }}-${{ matrix.bits }}-${{ matrix.compiler }} | |
| path: | | |
| src\downloads | |
| D:\cygwin-packages | |
| - | |
| name: Set variables | |
| id: vars | |
| shell: pwsh | |
| run: > | |
| ./service/case-vars.ps1 | |
| -Bits ${{ matrix.bits }} | |
| -Link ${{ matrix.link }} | |
| -Compiler ${{ matrix.compiler }} | |
| -InstalledPath installed | |
| -ToolsPath src\downloads | |
| -CLDRVersion '${{ needs.versions.outputs.cldr-version }}' | |
| -IconvVersion '${{ needs.versions.outputs.iconv-version }}' | |
| -CurlVersionDefault '${{ needs.versions.outputs.curl-version-default }}' | |
| -JsonCVersionDefault '${{ needs.versions.outputs.json-c-version-default }}' | |
| -GettextVersion '${{ needs.versions.outputs.gettext-version }}' | |
| -SignpathSigningPolicyDefault '${{ needs.versions.outputs.signpath-signing-policy-default }}' | |
| - | |
| name: Install Cygwin | |
| uses: cygwin/cygwin-install-action@v6 | |
| timeout-minutes: 60 | |
| with: | |
| packages: ${{ steps.vars.outputs.cygwin-packages }} | |
| install-dir: D:\cygwin | |
| work-vol: 'D:' | |
| site: ${{ needs.versions.outputs.cygwin-mirror }} | |
| add-to-path: false | |
| - | |
| name: Setup Cygwin environment | |
| run: | | |
| PATH='${{ steps.vars.outputs.cygwin-path }}' | |
| cd -- "$(cygpath -ua '${{ github.workspace }}')" | |
| cp ./LICENSE.txt installed/license.txt | |
| mkdir -p "$HOME" | |
| printf "\nPATH='${{ steps.vars.outputs.cygwin-path }}'\nexport PATH\n" >>$HOME/.bash_profile | |
| - | |
| name: Dump Cygwin environment | |
| run: | | |
| printf 'Current working directory: %s\n' "$(pwd)" | |
| echo 'PATH contains:' | |
| IFS=: | |
| for p in $PATH; do | |
| printf -- '- %s\n' "$p" | |
| done | |
| - | |
| name: Download FSF ar-lib | |
| if: matrix.compiler == 'msvc' | |
| shell: pwsh | |
| run: > | |
| ./service/download-archive.ps1 | |
| -Url 'https://git.savannah.gnu.org/gitweb/?p=automake.git;a=blob_plain;f=lib/ar-lib;hb=HEAD' | |
| -LocalFilePath src\downloads\ar-lib | |
| - | |
| name: Download FSF compile | |
| if: matrix.compiler == 'msvc' | |
| shell: pwsh | |
| run: > | |
| ./service/download-archive.ps1 | |
| -Url 'https://git.savannah.gnu.org/gitweb/?p=automake.git;a=blob_plain;f=lib/compile;hb=HEAD' | |
| -LocalFilePath src\downloads\compile | |
| - | |
| name: Download CLDR | |
| shell: pwsh | |
| run: > | |
| ./service/download-archive.ps1 | |
| -Url https://unicode.org/Public/cldr/${{ needs.versions.outputs.cldr-version }}/core.zip | |
| -LocalFilePath src\downloads\cldr-${{ needs.versions.outputs.cldr-version }}.zip | |
| - | |
| name: Download iconv artifact | |
| if: needs.versions.outputs.iconv-tarball-from-commit | |
| uses: actions/download-artifact@v7 | |
| with: | |
| artifact-ids: ${{ needs.build-iconv-tarball.outputs.artifact-id }} | |
| path: src/downloads/ | |
| - | |
| name: Download iconv | |
| if: ${{ !needs.versions.outputs.iconv-tarball-from-commit }} | |
| shell: pwsh | |
| run: > | |
| ./service/download-archive.ps1 | |
| -Url '${{ needs.versions.outputs.iconv-source-url }}' | |
| -LocalFilePath src\downloads\libiconv-${{ needs.versions.outputs.iconv-version }}.tar.gz | |
| - | |
| name: Download curl | |
| if: steps.vars.outputs.curl-version | |
| shell: pwsh | |
| run: > | |
| ./service/download-archive.ps1 | |
| -Url https://curl.se/download/curl-${{ steps.vars.outputs.curl-version }}.tar.gz | |
| -LocalFilePath src\downloads\curl-${{ steps.vars.outputs.curl-version }}.tar.gz | |
| - | |
| name: Download JSON-C | |
| if: steps.vars.outputs.json-c-version | |
| shell: pwsh | |
| run: > | |
| ./service/download-archive.ps1 | |
| -Url https://s3.amazonaws.com/json-c_releases/releases/json-c-${{ steps.vars.outputs.json-c-version }}-nodoc.tar.gz | |
| -LocalFilePath src\downloads\json-c-${{ steps.vars.outputs.json-c-version }}.tar.gz | |
| - | |
| name: Download gettext | |
| shell: pwsh | |
| run: > | |
| ./service/download-archive.ps1 | |
| -Url '${{ needs.versions.outputs.gettext-source-url }}' | |
| -LocalFilePath src\downloads\gettext-${{ needs.versions.outputs.gettext-version }}.tar.gz | |
| - | |
| name: Add GCC Runtime license | |
| if: matrix.compiler == 'gcc' | |
| run: | | |
| cp /usr/share/doc/mingw64-${{ steps.vars.outputs.mingw-architecture }}-gcc/COPYING installed/licenses/gcc.txt | |
| - | |
| name: Extract CLDR | |
| run: | | |
| unzip -p src/downloads/cldr-${{ needs.versions.outputs.cldr-version }}.zip LICENSE > installed/licenses/cldr.txt | |
| mkdir -p installed/share/gettext/cldr/common/supplemental | |
| unzip -p src/downloads/cldr-${{ needs.versions.outputs.cldr-version }}.zip common/supplemental/plurals.xml >installed/share/gettext/cldr/common/supplemental/plurals.xml | |
| - | |
| name: Simplify CLDR plurals.xml | |
| if: steps.vars.outputs.cldr-simplify-plurals-xml == 'yes' | |
| shell: pwsh | |
| run: ./service/simplify-plurals-xml.ps1 installed/share/gettext/cldr/common/supplemental/plurals.xml | |
| - | |
| name: Extract iconv | |
| run: | | |
| tar x -C src -z -f src/downloads/libiconv-${{ needs.versions.outputs.iconv-version }}.tar.gz | |
| cp src/libiconv-${{ needs.versions.outputs.iconv-version }}/COPYING installed/licenses/iconv.txt | |
| - | |
| name: Extract curl | |
| if: steps.vars.outputs.curl-version | |
| run: | | |
| tar x -C src -z -f src/downloads/curl-${{ steps.vars.outputs.curl-version }}.tar.gz | |
| cp src/curl-${{ steps.vars.outputs.curl-version }}/COPYING installed/licenses/curl.txt | |
| - | |
| name: Extract JSON-C | |
| if: steps.vars.outputs.json-c-version | |
| run: | | |
| tar x -C src -z -f src/downloads/json-c-${{ steps.vars.outputs.json-c-version }}.tar.gz | |
| cp src/json-c-${{ steps.vars.outputs.json-c-version }}/COPYING installed/licenses/json-c.txt | |
| - | |
| name: Extract gettext | |
| run: | | |
| tar x -C src -z -f src/downloads/gettext-${{ needs.versions.outputs.gettext-version }}.tar.gz | |
| cp src/gettext-${{ needs.versions.outputs.gettext-version }}/COPYING installed/licenses/gettext.txt | |
| - | |
| name: Apply patches | |
| run: | | |
| set -o errexit | |
| for dir in $(find src/* -maxdepth 1 -type d -printf '%f\n'); do | |
| if ! test -d "patches/$dir"; then | |
| continue | |
| fi | |
| printf 'Applying patches for %s\n' "$dir" | |
| for patchfile in $(find patches/$dir -maxdepth 1 -type f -printf '%f\n' | sort); do | |
| printf -- '- %s\n' "$patchfile" | |
| patch -d "src/$dir" -p1 -u <"patches/$dir/$patchfile" | |
| done | |
| done | |
| - | |
| name: Configure iconv (1st time) | |
| id: iconv-configure | |
| working-directory: src\libiconv-${{ needs.versions.outputs.iconv-version }} | |
| env: | |
| INCLUDE: ${{ steps.vars.outputs.include-env-var }} | |
| LIB: ${{ steps.vars.outputs.lib-env-var }} | |
| run: | | |
| mkdir build | |
| cd build | |
| ../configure ${{ steps.vars.outputs.iconv-configure-args }} | |
| - | |
| name: Compile iconv (1st time) | |
| working-directory: src\libiconv-${{ needs.versions.outputs.iconv-version }}\build | |
| env: | |
| INCLUDE: ${{ steps.vars.outputs.include-env-var }} | |
| LIB: ${{ steps.vars.outputs.lib-env-var }} | |
| run: make --jobs=$(nproc) | |
| - | |
| name: Check iconv (1st time) | |
| working-directory: src\libiconv-${{ needs.versions.outputs.iconv-version }}\build | |
| env: | |
| INCLUDE: ${{ steps.vars.outputs.include-env-var }} | |
| LIB: ${{ steps.vars.outputs.lib-env-var }} | |
| run: make --jobs=$(nproc) check | |
| - | |
| name: Install iconv (1st time) | |
| working-directory: src\libiconv-${{ needs.versions.outputs.iconv-version }}\build | |
| env: | |
| INCLUDE: ${{ steps.vars.outputs.include-env-var }} | |
| LIB: ${{ steps.vars.outputs.lib-env-var }} | |
| run: make --jobs=$(nproc) ${{ steps.vars.outputs.make-install-argument }} | |
| - | |
| name: Configure curl | |
| if: steps.vars.outputs.curl-version | |
| id: curl-configure | |
| working-directory: src\curl-${{ steps.vars.outputs.curl-version }} | |
| env: | |
| INCLUDE: ${{ steps.vars.outputs.include-env-var }} | |
| LIB: ${{ steps.vars.outputs.lib-env-var }} | |
| run: | | |
| mkdir build | |
| cd build | |
| ../configure ${{ steps.vars.outputs.curl-configure-args }} | |
| if [ "$(./curl-config --built-shared)" = yes ]; then | |
| libs="$(./curl-config --libs)" | |
| else | |
| libs="$(./curl-config --static-libs)" | |
| fi | |
| echo "libs=$libs" >>"$GITHUB_OUTPUT" | |
| echo 'OUTPUTS:' | |
| cat "$GITHUB_OUTPUT" | |
| - | |
| name: Install curl - libcurl | |
| if: steps.vars.outputs.curl-version | |
| working-directory: src\curl-${{ steps.vars.outputs.curl-version }}\build\lib | |
| env: | |
| INCLUDE: ${{ steps.vars.outputs.include-env-var }} | |
| LIB: ${{ steps.vars.outputs.lib-env-var }} | |
| run: make --jobs=$(nproc) ${{ steps.vars.outputs.make-install-argument }} | |
| - | |
| name: Install curl - include | |
| if: steps.vars.outputs.curl-version | |
| working-directory: src\curl-${{ steps.vars.outputs.curl-version }}\build\include | |
| env: | |
| INCLUDE: ${{ steps.vars.outputs.include-env-var }} | |
| LIB: ${{ steps.vars.outputs.lib-env-var }} | |
| run: make --jobs=$(nproc) ${{ steps.vars.outputs.make-install-argument }} | |
| - | |
| name: Prepare JSON-C | |
| if: steps.vars.outputs.json-c-version | |
| working-directory: src\json-c-${{ steps.vars.outputs.json-c-version }} | |
| env: | |
| INCLUDE: ${{ steps.vars.outputs.include-env-var }} | |
| LIB: ${{ steps.vars.outputs.lib-env-var }} | |
| run: | | |
| mkdir build | |
| cd build | |
| cmake ${{ steps.vars.outputs.json-c-cmake-args }} \ | |
| ../ | |
| - | |
| name: Build JSON-C | |
| if: steps.vars.outputs.json-c-version | |
| working-directory: src\json-c-${{ steps.vars.outputs.json-c-version }}\build | |
| env: | |
| INCLUDE: ${{ steps.vars.outputs.include-env-var }} | |
| LIB: ${{ steps.vars.outputs.lib-env-var }} | |
| run: make --jobs=$(nproc) all | |
| - | |
| name: Install JSON-C | |
| if: steps.vars.outputs.json-c-version | |
| working-directory: src\json-c-${{ steps.vars.outputs.json-c-version }}\build | |
| env: | |
| INCLUDE: ${{ steps.vars.outputs.include-env-var }} | |
| LIB: ${{ steps.vars.outputs.lib-env-var }} | |
| run: make install/strip | |
| - | |
| name: Configure gettext | |
| id: gettext-configure | |
| working-directory: src\gettext-${{ needs.versions.outputs.gettext-version }} | |
| env: | |
| INCLUDE: ${{ steps.vars.outputs.include-env-var }} | |
| LIB: ${{ steps.vars.outputs.lib-env-var }} | |
| run: | | |
| mkdir build | |
| cd build | |
| ../configure \ | |
| LIBS='${{ steps.curl-configure.outputs.libs }}' ${{ steps.vars.outputs.gettext-configure-args }} | |
| - | |
| name: Ignore gettext C tests | |
| if: steps.vars.outputs.gettext-ignore-c-tests | |
| working-directory: src\gettext-${{ needs.versions.outputs.gettext-version }} | |
| run: for f in ${{ steps.vars.outputs.gettext-ignore-c-tests }}; do echo 'int main() { return 0; }' >$f; done | |
| - | |
| name: Compile gettext/gnulib-local | |
| working-directory: src\gettext-${{ needs.versions.outputs.gettext-version }}\build\gnulib-local | |
| env: | |
| INCLUDE: ${{ steps.vars.outputs.include-env-var }} | |
| LIB: ${{ steps.vars.outputs.lib-env-var }} | |
| run: make --jobs=$(nproc) | |
| - | |
| name: Check gettext/gnulib-local | |
| working-directory: src\gettext-${{ needs.versions.outputs.gettext-version }}\build\gnulib-local | |
| env: | |
| INCLUDE: ${{ steps.vars.outputs.include-env-var }} | |
| LIB: ${{ steps.vars.outputs.lib-env-var }} | |
| run: make --jobs=$(nproc) check | |
| - | |
| name: Install gettext/gnulib-local | |
| working-directory: src\gettext-${{ needs.versions.outputs.gettext-version }}\build\gnulib-local | |
| env: | |
| INCLUDE: ${{ steps.vars.outputs.include-env-var }} | |
| LIB: ${{ steps.vars.outputs.lib-env-var }} | |
| run: make --jobs=$(nproc) ${{ steps.vars.outputs.make-install-argument }} | |
| - | |
| name: Compile gettext/gettext-runtime | |
| working-directory: src\gettext-${{ needs.versions.outputs.gettext-version }}\build\gettext-runtime | |
| env: | |
| INCLUDE: ${{ steps.vars.outputs.include-env-var }} | |
| LIB: ${{ steps.vars.outputs.lib-env-var }} | |
| run: make --jobs=$(nproc) | |
| - | |
| name: Check gettext/gettext-runtime | |
| working-directory: src\gettext-${{ needs.versions.outputs.gettext-version }}\build\gettext-runtime | |
| env: | |
| INCLUDE: ${{ steps.vars.outputs.include-env-var }} | |
| LIB: ${{ steps.vars.outputs.lib-env-var }} | |
| run: make --jobs=$(nproc) check | |
| - | |
| name: Install gettext/gettext-runtime | |
| working-directory: src\gettext-${{ needs.versions.outputs.gettext-version }}\build\gettext-runtime | |
| env: | |
| INCLUDE: ${{ steps.vars.outputs.include-env-var }} | |
| LIB: ${{ steps.vars.outputs.lib-env-var }} | |
| run: make --jobs=$(nproc) ${{ steps.vars.outputs.make-install-argument }} | |
| - | |
| name: Compile gettext/libtextstyle | |
| working-directory: src\gettext-${{ needs.versions.outputs.gettext-version }}\build\libtextstyle | |
| env: | |
| INCLUDE: ${{ steps.vars.outputs.include-env-var }} | |
| LIB: ${{ steps.vars.outputs.lib-env-var }} | |
| run: make --jobs=$(nproc) | |
| - | |
| name: Check gettext/libtextstyle | |
| working-directory: src\gettext-${{ needs.versions.outputs.gettext-version }}\build\libtextstyle | |
| env: | |
| INCLUDE: ${{ steps.vars.outputs.include-env-var }} | |
| LIB: ${{ steps.vars.outputs.lib-env-var }} | |
| run: make --jobs=$(nproc) check | |
| - | |
| name: Install gettext/libtextstyle | |
| working-directory: src\gettext-${{ needs.versions.outputs.gettext-version }}\build\libtextstyle | |
| env: | |
| INCLUDE: ${{ steps.vars.outputs.include-env-var }} | |
| LIB: ${{ steps.vars.outputs.lib-env-var }} | |
| run: make --jobs=$(nproc) ${{ steps.vars.outputs.make-install-argument }} | |
| - | |
| name: Compile gettext/gettext-tools | |
| working-directory: src\gettext-${{ needs.versions.outputs.gettext-version }}\build\gettext-tools | |
| env: | |
| INCLUDE: ${{ steps.vars.outputs.include-env-var }} | |
| LIB: ${{ steps.vars.outputs.lib-env-var }} | |
| run: make --jobs=$(nproc) | |
| - | |
| name: Check gettext/gettext-tools | |
| working-directory: src\gettext-${{ needs.versions.outputs.gettext-version }}\build\gettext-tools | |
| env: | |
| INCLUDE: ${{ steps.vars.outputs.include-env-var }} | |
| LIB: ${{ steps.vars.outputs.lib-env-var }} | |
| run: XFAIL_TESTS='${{ steps.vars.outputs.gettext-xfail-gettext-tools }}' make --jobs=$(nproc) check | |
| - | |
| name: Install gettext/gettext-tools | |
| working-directory: src\gettext-${{ needs.versions.outputs.gettext-version }}\build\gettext-tools | |
| env: | |
| INCLUDE: ${{ steps.vars.outputs.include-env-var }} | |
| LIB: ${{ steps.vars.outputs.lib-env-var }} | |
| run: make --jobs=$(nproc) ${{ steps.vars.outputs.make-install-argument }} | |
| - | |
| # We need to rebuild iconv because it depends on gettext's libintl in order to be localizable | |
| name: Configure iconv (2nd time) | |
| working-directory: src\libiconv-${{ needs.versions.outputs.iconv-version }} | |
| env: | |
| INCLUDE: ${{ steps.vars.outputs.include-env-var }} | |
| LIB: ${{ steps.vars.outputs.lib-env-var }} | |
| run: | | |
| rm -rf build | |
| mkdir build | |
| cd build | |
| ../configure ${{ steps.vars.outputs.iconv-configure-args }} \ | |
| --enable-extra-encodings | |
| - | |
| name: Compile iconv (2nd time) | |
| working-directory: src\libiconv-${{ needs.versions.outputs.iconv-version }}\build | |
| env: | |
| INCLUDE: ${{ steps.vars.outputs.include-env-var }} | |
| LIB: ${{ steps.vars.outputs.lib-env-var }} | |
| run: make --jobs=$(nproc) | |
| - | |
| name: Check iconv (2nd time) | |
| working-directory: src\libiconv-${{ needs.versions.outputs.iconv-version }}\build | |
| env: | |
| INCLUDE: ${{ steps.vars.outputs.include-env-var }} | |
| LIB: ${{ steps.vars.outputs.lib-env-var }} | |
| run: make --jobs=$(nproc) check | |
| - | |
| name: Install iconv (2nd time) | |
| working-directory: src\libiconv-${{ needs.versions.outputs.iconv-version }}\build | |
| env: | |
| INCLUDE: ${{ steps.vars.outputs.include-env-var }} | |
| LIB: ${{ steps.vars.outputs.lib-env-var }} | |
| run: make --jobs=$(nproc) ${{ steps.vars.outputs.make-install-argument }} | |
| - | |
| name: Finalize install dir | |
| shell: pwsh | |
| run: > | |
| ./service/finalize-installed.ps1 | |
| -Bits ${{ matrix.bits }} | |
| -Link ${{ matrix.link }} | |
| -Path installed | |
| -MinGWPath ${{ matrix.compiler == 'mscv' && '' || format('D:\\cygwin\\usr\\{0}', steps.vars.outputs.mingw-host) }} | |
| - | |
| name: Extract version infos | |
| id: versioninfos | |
| shell: pwsh | |
| run: ./service/extract-versiononfos.ps1 -RootPath installed | |
| - | |
| name: Check bitness | |
| run: ./service/check-bits.sh ${{ matrix.bits }} installed | |
| - | |
| name: Upload unsigned files | |
| if: steps.vars.outputs.signpath-signing-policy | |
| id: upload-installed-unsigned | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: tobesigned-installed-${{ matrix.link }}-${{ matrix.bits }}-${{ matrix.compiler }} | |
| path: | | |
| installed/**/*.dll | |
| installed/**/*.exe | |
| if-no-files-found: error | |
| retention-days: 1 | |
| - | |
| name: Sign files | |
| if: steps.vars.outputs.signpath-signing-policy | |
| id: sign-files | |
| uses: signpath/github-action-submit-signing-request@v2 | |
| with: | |
| api-token: '${{ secrets.SIGNPATH_API_TOKEN }}' | |
| organization-id: 98c3accc-92c9-4962-b150-ff1f5c6356b8 | |
| project-slug: gettext-iconv-windows | |
| signing-policy-slug: '${{ steps.vars.outputs.signpath-signing-policy }}' | |
| artifact-configuration-slug: ${{ needs.versions.outputs.signpath-artifactconfiguration-files }} | |
| github-artifact-id: ${{ steps.upload-installed-unsigned.outputs.artifact-id }} | |
| wait-for-completion: true | |
| output-artifact-directory: installed | |
| parameters: ${{ steps.versioninfos.outputs.signpath-parameters }} | |
| - | |
| name: Check signatures | |
| if: steps.vars.outputs.signpath-signing-policy | |
| shell: pwsh | |
| run: > | |
| ./service/check-signature.ps1 | |
| -GettextVersion ${{ needs.versions.outputs.gettext-version }} | |
| -Path installed | |
| -CanBeInvalid ${{ needs.versions.outputs.signatures-canbeinvalid == 'yes' && '$true' || '$false' }} | |
| - | |
| name: Copy built developer files | |
| shell: pwsh | |
| run: ./service/copy-output.ps1 -Type dev -From installed -To output-dev | |
| - | |
| name: Create developer files archive | |
| shell: pwsh | |
| working-directory: output-dev | |
| run: | | |
| & 7z.exe a -bd -bt -mx9 -r -sse -tzip ..\assets\gettext${{ needs.versions.outputs.gettext-version }}-iconv${{ needs.versions.outputs.iconv-version-base }}-${{ matrix.link }}-${{ matrix.bits }}-dev-${{ matrix.compiler }}.zip | |
| - | |
| name: Copy built executables | |
| shell: pwsh | |
| run: ./service/copy-output.ps1 -Type exe -From installed -To output-exe | |
| - | |
| name: Delete unused dependencies | |
| shell: pwsh | |
| run: ./service/delete-unused-dependencies.ps1 -Bits ${{ matrix.bits }} -Link ${{ matrix.link }} -Path output-exe | |
| - | |
| name: Create executable files archive | |
| if: steps.vars.outputs.collect-programs == 'yes' | |
| shell: pwsh | |
| working-directory: output-exe | |
| run: | | |
| & 7z.exe a -bd -bt -mx9 -r -sse -tzip ..\assets\gettext${{ needs.versions.outputs.gettext-version }}-iconv${{ needs.versions.outputs.iconv-version-base }}-${{ matrix.link }}-${{ matrix.bits }}.zip | |
| - | |
| name: Prepare build log | |
| id: prepare-build-log | |
| if: (success() || failure()) && (steps.iconv-configure.outcome == 'success' || steps.iconv-configure.outcome == 'failure') | |
| run: | | |
| mkdir build-log | |
| if [ -d src/libiconv-${{ needs.versions.outputs.iconv-version }}/build ]; then | |
| tar c -J -f build-log/iconv.tar.xz src/libiconv-${{ needs.versions.outputs.iconv-version }}/build | |
| fi | |
| if [ -d src/curl-${{ steps.vars.outputs.curl-version }}/build ]; then | |
| tar c -J -f build-log/curl.tar.xz src/curl-${{ steps.vars.outputs.curl-version }}/build | |
| fi | |
| if [ -d src/json-c-${{ steps.vars.outputs.json-c-version }}/build ]; then | |
| tar c -J -f build-log/json-c.tar.xz src/json-c-${{ steps.vars.outputs.json-c-version }}/build | |
| fi | |
| if [ -d src/gettext-${{ needs.versions.outputs.gettext-version }}/build ]; then | |
| tar c -J -f build-log/gettext.tar.xz src/gettext-${{ needs.versions.outputs.gettext-version }}/build | |
| fi | |
| if [ -d installed ]; then | |
| if find installed -mindepth 1 -maxdepth 1 | read; then | |
| tar c -J -f build-log/installed.tar.xz installed | |
| fi | |
| fi | |
| ls -al build-log | |
| - | |
| name: Delete install directory | |
| run: rm -rf installed | |
| - | |
| name: Check if iconv program load translations correctly | |
| shell: pwsh | |
| run: | | |
| $env:LANGUAGE = 'it' | |
| $stdout = & .\output-exe\bin\iconv.exe --help | |
| if (-not($?)) { | |
| throw "iconv.exe failed" | |
| } | |
| $stdout = $stdout -join "`n" | |
| if (!$stdout.Contains('formato di input')) { | |
| throw "iconv.exe didn't load the translations.`nIts output is:`n$stdout" | |
| } | |
| Write-Host "iconv.exe correctly loaded the translations when LANGUAGE=$env:LANGUAGE`nIts localized output is`n$stdout" | |
| - | |
| name: Check if gettext programs load translations correctly | |
| shell: pwsh | |
| run: | | |
| $env:LANGUAGE = 'it' | |
| $stdout = & .\output-exe\bin\xgettext.exe --help | |
| if (-not($?)) { | |
| throw "xgettext.exe failed" | |
| } | |
| $stdout = $stdout -join "`n" | |
| if (!$stdout.Contains('impostazione predefinita')) { | |
| throw "xgettext.exe didn't load the translations.`nIts output is:`n$stdout" | |
| } | |
| Write-Host "xgettext.exe correctly loaded the translations when LANGUAGE=$env:LANGUAGE`nIts localized output is`n$stdout" | |
| - | |
| name: Check cldr-plurals | |
| shell: pwsh | |
| run: | | |
| $pot = @' | |
| msgid "" | |
| msgstr "" | |
| "Content-Type: text/plain; charset=UTF-8\n" | |
| "MIME-Version: 1.0\n" | |
| "Content-Transfer-Encoding: 8bit\n" | |
| msgid "Hi" | |
| msgstr "" | |
| '@ | |
| $lang = 'zu' | |
| Remove-Item -LiteralPath Env:GETTEXTCLDRDIR -ErrorAction SilentlyContinue | |
| $po = $pot | & .\output-exe\bin\msginit.exe --input=- --output-file=- --locale="$lang" | |
| $rule = $po -match "Plural-Forms:" | |
| if ($rule) { | |
| throw "Without GETTEXTCLDRDIR there shouldn't be a Plural-Forms header in the .po file for the locale $lang, but we found it: $rule" | |
| } | |
| Write-Output -InputObject "As expected, without GETTEXTCLDRDIR there isn't a Plural-Forms header in the .po file for the locale $lang." | |
| $env:GETTEXTCLDRDIR = "$PWD\output-exe\share\gettext\cldr" | |
| $po = $pot | & .\output-exe\bin\msginit.exe --input=- --output-file=- --locale="$lang" | |
| $rule = $po -match "Plural-Forms:" | |
| if ('${{ steps.vars.outputs.cldr-plural-works }}' -eq 'yes') { | |
| if (-not($rule)) { | |
| throw "With GETTEXTCLDRDIR there should be a Plural-Forms header in the .po file for the locale $lang, but there isn't." | |
| } | |
| Write-Output -InputObject "With GETTEXTCLDRDIR there is a Plural-Forms header ($rule) in the .po file for the locale $lang." | |
| } else { | |
| if ($rule) { | |
| throw "Even with GETTEXTCLDRDIR there shouldn't be a Plural-Forms header in the .po file for the locale $lang, but we found it: $rule" | |
| } | |
| Write-Output -InputObject "As expected, even with GETTEXTCLDRDIR there isn't a Plural-Forms header in the .po file for the locale $lang." | |
| } | |
| - | |
| name: Start fake ollama server | |
| if: steps.vars.outputs.check-spit-exe == 'yes' | |
| id: start-fake-ollama-server | |
| shell: pwsh | |
| run: | | |
| $process = Start-Process pwsh -ArgumentList '.\service\run-fake-ollama-server.ps1' -WindowStyle Hidden -PassThru | |
| Start-Sleep -Seconds 2 | |
| $process.Refresh() | |
| if ($process.HasExited) { | |
| throw 'Failed to start fake ollama server' | |
| } | |
| Write-Host "Started fake ollama server (process ID: $($process.Id))" | |
| "pid=$($process.Id)" | Out-File -FilePath $env:GITHUB_OUTPUT -Append -Encoding utf8 | |
| - | |
| name: Check spit executable | |
| if: steps.vars.outputs.check-spit-exe == 'yes' | |
| shell: pwsh | |
| run: | | |
| $spitPath = '.\output-exe\bin\spit.exe' | |
| if (-not(Test-Path -LiteralPath $spitPath -PathType Leaf)) { | |
| throw "spit.exe not found at expected path: $spitPath" | |
| } | |
| $stdout = Write-Output 'Test' | & $spitPath --model=llama3.2:3b --to=fr | |
| if (-not($?)) { | |
| throw "spit.exe failed" | |
| } | |
| $stdout = $stdout -join "`n" | |
| if ($stdout -ne "Ollama answer to prompt Translate into French:`nTest") { | |
| throw "spit.exe output is unexpected.`nIts output is:`n$stdout" | |
| } | |
| Write-Host "spit.exe executed correctly.`nIts output is`n$stdout" | |
| - | |
| name: Stop fake ollama server | |
| if: (success() || failure()) && steps.start-fake-ollama-server.outcome == 'success' | |
| shell: pwsh | |
| run: | | |
| try { | |
| $process = Get-Process -Id ${{ steps.start-fake-ollama-server.outputs.pid }} | |
| } catch { | |
| $process = $null | |
| } | |
| if ($null -ne $process) { | |
| $process.Kill($true) | |
| } | |
| - | |
| name: Create installer | |
| if: steps.vars.outputs.collect-programs == 'yes' | |
| shell: pwsh | |
| run: > | |
| ./service/create-installer.ps1 | |
| -Bits ${{ matrix.bits }} | |
| -Link ${{ matrix.link }} | |
| -SourceDirectory output-exe | |
| -OutputDirectory assets | |
| -IconvVersion ${{ needs.versions.outputs.iconv-version-base }} | |
| -GettextVersion ${{ needs.versions.outputs.gettext-version }} | |
| - | |
| name: Check bitness | |
| if: steps.vars.outputs.collect-programs == 'yes' | |
| run: ./service/check-bits.sh 32 assets/gettext${{ needs.versions.outputs.gettext-version }}-iconv${{ needs.versions.outputs.iconv-version-base }}-${{ matrix.link }}-${{ matrix.bits }}.exe | |
| - | |
| name: Upload unsigned installer | |
| if: steps.vars.outputs.collect-programs == 'yes' && steps.vars.outputs.signpath-signing-policy | |
| id: upload-installer-unsigned | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: tobesigned-installer-${{ matrix.link }}-${{ matrix.bits }}-${{ matrix.compiler }} | |
| path: assets/gettext${{ needs.versions.outputs.gettext-version }}-iconv${{ needs.versions.outputs.iconv-version-base }}-${{ matrix.link }}-${{ matrix.bits }}.exe | |
| if-no-files-found: error | |
| compression-level: 0 | |
| retention-days: 1 | |
| - | |
| name: Sign installer | |
| if: steps.vars.outputs.collect-programs == 'yes' && steps.vars.outputs.signpath-signing-policy | |
| id: sign-installer | |
| uses: signpath/github-action-submit-signing-request@v2 | |
| with: | |
| api-token: '${{ secrets.SIGNPATH_API_TOKEN }}' | |
| organization-id: 98c3accc-92c9-4962-b150-ff1f5c6356b8 | |
| project-slug: gettext-iconv-windows | |
| signing-policy-slug: '${{ steps.vars.outputs.signpath-signing-policy }}' | |
| artifact-configuration-slug: gh_sign_installer | |
| github-artifact-id: ${{ steps.upload-installer-unsigned.outputs.artifact-id }} | |
| wait-for-completion: true | |
| output-artifact-directory: assets | |
| - | |
| name: Check signature | |
| if: steps.vars.outputs.collect-programs == 'yes' && steps.vars.outputs.signpath-signing-policy | |
| shell: pwsh | |
| run: > | |
| ./service/check-signature.ps1 | |
| -GettextVersion ${{ needs.versions.outputs.gettext-version }} | |
| -Path assets/gettext${{ needs.versions.outputs.gettext-version }}-iconv${{ needs.versions.outputs.iconv-version-base }}-${{ matrix.link }}-${{ matrix.bits }}.exe | |
| -CanBeInvalid ${{ needs.versions.outputs.signatures-canbeinvalid == 'yes' && '$true' || '$false' }} | |
| - | |
| name: Upload assets | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: assets-${{ matrix.link }}-${{ matrix.bits }}-${{ matrix.compiler }} | |
| path: assets/* | |
| if-no-files-found: error | |
| compression-level: 0 | |
| - | |
| name: Upload build log | |
| if: always() && steps.prepare-build-log.outcome == 'success' | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: log-${{ matrix.link }}-${{ matrix.bits }}-${{ matrix.compiler }} | |
| if-no-files-found: ignore | |
| retention-days: 1 | |
| include-hidden-files: true | |
| compression-level: 0 | |
| path: build-log | |
| - | |
| name: Persist cache | |
| if: always() && steps.restore-cache.outputs.cache-hit != 'true' | |
| uses: actions/cache/save@v5 | |
| with: | |
| key: ${{ steps.restore-cache.outputs.cache-primary-key }} | |
| path: | | |
| src\downloads | |
| D:\cygwin-packages | |
| publish-release: | |
| name: Publish release | |
| needs: | |
| - versions | |
| - build | |
| if: needs.versions.outputs.release-tag | |
| runs-on: ubuntu-latest | |
| steps: | |
| - | |
| name: Create assets directory | |
| run: mkdir -p assets | |
| - | |
| name: Download assets | |
| uses: actions/download-artifact@v7 | |
| with: | |
| path: assets | |
| pattern: assets-* | |
| merge-multiple: true | |
| - | |
| name: Publish release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| name: ${{ needs.versions.outputs.release-tag }} | |
| tag_name: ${{ needs.versions.outputs.release-tag }} | |
| files: assets/* | |
| fail_on_unmatched_files: true | |
| prerelease: ${{ needs.versions.outputs.is-prerelease == 'yes' && 'true' || 'false' }} | |
| make_latest: ${{ needs.versions.outputs.is-prerelease == 'yes' && 'false' || 'true' }} | |
| body: | | |
| ## Components | |
| * gettext ${{ needs.versions.outputs.gettext-version }} | |
| * iconv ${{ needs.versions.outputs.iconv-version-base }} | |
| * libcurl ${{ needs.versions.outputs.curl-version-default }} | |
| * libjson-c ${{ needs.versions.outputs.json-c-version-default }} | |
| * CLDR ${{ needs.versions.outputs.cldr-version }} | |
| generate_release_notes: true |