Bump fortran-lang/setup-fpm from 7 to 8 #2800
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: | |
| pull_request: | |
| release: | |
| types: [published] | |
| env: | |
| CI: "ON" # We can detect this in the build system and other vendors implement it | |
| HOMEBREW_NO_ANALYTICS: "ON" # Make Homebrew installation a little quicker | |
| HOMEBREW_NO_AUTO_UPDATE: "ON" | |
| HOMEBREW_NO_BOTTLE_SOURCE_FALLBACK: "ON" | |
| HOMEBREW_NO_GITHUB_API: "ON" | |
| HOMEBREW_NO_INSTALL_CLEANUP: "ON" | |
| jobs: | |
| build: | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-14, windows-latest] | |
| toolchain: | |
| - {compiler: gcc, version: 10} | |
| - {compiler: gcc, version: 11} | |
| - {compiler: gcc, version: 12} | |
| - {compiler: gcc, version: 13} | |
| - {compiler: gcc, version: 14} | |
| - {compiler: gcc, version: 15} | |
| - {compiler: intel, version: 2025.2} | |
| exclude: | |
| - os: macos-14 # No Intel on MacOS anymore since 2024 | |
| toolchain: {compiler: intel, version: '2025.1'} | |
| - os: macos-14 # Intel compiler does not support ARM (macos-14) | |
| toolchain: {compiler: intel, version: '2025.2'} | |
| - os: macos-14 # gcc@10 not available on macos-14 (ARM64) | |
| toolchain: {compiler: gcc, version: 10} | |
| - os: windows-latest # Doesn't pass build and tests yet | |
| toolchain: {compiler: intel, version: '2025.2'} | |
| - os: windows-latest # gcc 14 not available on Windows yet | |
| toolchain: {compiler: gcc, version: 14} | |
| - os: windows-latest # gcc 15 not available on Windows yet | |
| toolchain: {compiler: gcc, version: 15} | |
| - os: ubuntu-latest # gcc 15 not available on Ubuntu via setup-fortran yet | |
| toolchain: {compiler: gcc, version: 15} | |
| include: | |
| - os: ubuntu-latest | |
| os-arch: linux-x86_64 | |
| release-flags: --flag '--static -g -fbacktrace -O3' | |
| - os: macos-14 | |
| os-arch: macos-x86_64 | |
| release-flags: --flag '-g -fbacktrace -O3' | |
| - os: windows-latest | |
| os-arch: windows-x86_64 | |
| release-flags: --flag '--static -g -fbacktrace -O3' | |
| exe: .exe | |
| - os: macos-14 | |
| toolchain: {compiler: gcc, version: 15} | |
| release-flags: --flag '-g -fbacktrace -Og -fcheck=all,no-recursion -Wno-external-argument-mismatch' | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v5 | |
| - name: Setup Fortran compiler | |
| uses: fortran-lang/[email protected] | |
| id: setup-fortran | |
| with: | |
| compiler: ${{ matrix.toolchain.compiler }} | |
| version: ${{ matrix.toolchain.version }} | |
| # Phase 1: Bootstrap fpm with existing version | |
| - name: Install fpm | |
| uses: fortran-lang/setup-fpm@v8 | |
| with: | |
| fpm-version: 'v0.12.0' | |
| # Backport gfortran shared libraries to the paths expected by the bootstrap fpm binary. | |
| # The macOS x86_64 release used for bootstrapping has hardcoded library paths from the gcc version | |
| # it was built with. If the versions match, skip this step. Otherwise, create symlinks. | |
| # On ARM64 it runs under Rosetta 2 and needs /usr/local paths. | |
| - name: MacOS patch libgfortran | |
| if: contains(matrix.os, 'macos') | |
| run: | | |
| which gfortran-${{ matrix.toolchain.version }} | |
| which gfortran | |
| BREW_PREFIX=$(brew --prefix) | |
| # Query the actual library paths that fpm expects | |
| echo "Checking library dependencies of fpm bootstrap binary..." | |
| otool -L $(which fpm) | |
| # Extract the gcc version from the bootstrap binary's library paths | |
| BOOTSTRAP_GCC_VERSION=$(otool -L $(which fpm) | grep -o 'gcc@[0-9]\+' | head -n 1 | cut -d@ -f2) | |
| if [ -z "$BOOTSTRAP_GCC_VERSION" ]; then | |
| # Try alternative pattern: /lib/gcc/13/ -> extract 13 | |
| BOOTSTRAP_GCC_VERSION=$(otool -L $(which fpm) | grep libgfortran | grep -o '/lib/gcc/[0-9]\+/' | grep -o '[0-9]\+' | head -n 1) | |
| fi | |
| echo "Bootstrap fpm built with gcc@$BOOTSTRAP_GCC_VERSION" | |
| echo "Current toolchain: gcc@${{ matrix.toolchain.version }}" | |
| if [ "$BOOTSTRAP_GCC_VERSION" == "${{ matrix.toolchain.version }}" ]; then | |
| echo "✓ Bootstrap gcc version matches current toolchain - no patching needed" | |
| exit 0 | |
| fi | |
| echo "⚠ Version mismatch detected - creating compatibility symlinks..." | |
| # Find the actual Cellar path by following the symlink | |
| if [ -L "${BREW_PREFIX}/opt/gcc@${{ matrix.toolchain.version }}" ]; then | |
| GCC_CELLAR_PATH=$(cd -P "${BREW_PREFIX}/opt/gcc@${{ matrix.toolchain.version }}" && pwd) | |
| else | |
| GCC_CELLAR_PATH="${BREW_PREFIX}/Cellar/gcc@${{ matrix.toolchain.version }}"/* | |
| fi | |
| echo "GCC Cellar path: $GCC_CELLAR_PATH" | |
| # Find the actual library files | |
| CURRENT_GFORTRAN=$(find "$GCC_CELLAR_PATH"/lib/gcc/${{ matrix.toolchain.version }} -name "libgfortran.*.dylib" 2>/dev/null | head -n 1) | |
| CURRENT_QUADMATH=$(find "$GCC_CELLAR_PATH"/lib/gcc/${{ matrix.toolchain.version }} -name "libquadmath.*.dylib" 2>/dev/null | head -n 1) | |
| CURRENT_GCC_S=$(find "$GCC_CELLAR_PATH"/lib/gcc/${{ matrix.toolchain.version }} -name "libgcc_s.*.dylib" 2>/dev/null | head -n 1) | |
| echo "Current gcc@${{ matrix.toolchain.version }} libraries:" | |
| echo " libgfortran: $CURRENT_GFORTRAN" | |
| echo " libquadmath: $CURRENT_QUADMATH" | |
| echo " libgcc_s: $CURRENT_GCC_S" | |
| # Extract the expected libgfortran path and create symlink | |
| LIBGFORTRAN_PATH=$(otool -L $(which fpm) | grep libgfortran | awk '{print $1}' | head -n 1) | |
| if [ -n "$LIBGFORTRAN_PATH" ] && [ -n "$CURRENT_GFORTRAN" ]; then | |
| TARGET_DIR=$(dirname "$LIBGFORTRAN_PATH") | |
| echo "Creating directory: $TARGET_DIR" | |
| sudo mkdir -p "$TARGET_DIR" | |
| echo "Linking $CURRENT_GFORTRAN to $LIBGFORTRAN_PATH" | |
| sudo ln -fs "$CURRENT_GFORTRAN" "$LIBGFORTRAN_PATH" | |
| fi | |
| # Extract the expected libquadmath path and create symlink | |
| LIBQUADMATH_PATH=$(otool -L $(which fpm) | grep libquadmath | awk '{print $1}' | head -n 1) | |
| if [ -n "$LIBQUADMATH_PATH" ] && [ -n "$CURRENT_QUADMATH" ]; then | |
| TARGET_DIR=$(dirname "$LIBQUADMATH_PATH") | |
| echo "Creating directory: $TARGET_DIR" | |
| sudo mkdir -p "$TARGET_DIR" | |
| echo "Linking $CURRENT_QUADMATH to $LIBQUADMATH_PATH" | |
| sudo ln -fs "$CURRENT_QUADMATH" "$LIBQUADMATH_PATH" | |
| fi | |
| # Extract the expected libgcc_s path and create symlink | |
| LIBGCC_PATH=$(otool -L $(which fpm) | grep libgcc_s | awk '{print $1}' | head -n 1) | |
| if [ -n "$LIBGCC_PATH" ] && [ -n "$CURRENT_GCC_S" ]; then | |
| TARGET_DIR=$(dirname "$LIBGCC_PATH") | |
| echo "Creating directory: $TARGET_DIR" | |
| sudo mkdir -p "$TARGET_DIR" | |
| echo "Linking $CURRENT_GCC_S to $LIBGCC_PATH" | |
| sudo ln -fs "$CURRENT_GCC_S" "$LIBGCC_PATH" | |
| fi | |
| # gcc and g++ will point to clang/clang++: use versioned alias for fpm | |
| - name: MacOS patch C and C++ compilers | |
| if: contains(matrix.os, 'macos') | |
| run: | | |
| echo "CC=gcc-${{ matrix.toolchain.version }}" >> $GITHUB_ENV | |
| echo "FPM_CC=gcc-${{ matrix.toolchain.version }}" >> $GITHUB_ENV | |
| echo "CXX=g++-${{ matrix.toolchain.version }}" >> $GITHUB_ENV | |
| echo "FPM_CXX=g++-${{ matrix.toolchain.version }}" >> $GITHUB_ENV | |
| echo "FPM_LDFLAGS=-lstdc++" >> $GITHUB_ENV | |
| - name: Remove fpm from path | |
| shell: bash | |
| run: | | |
| mv $(which fpm) fpm-bootstrap${{ matrix.exe }} | |
| echo "BOOTSTRAP=$PWD/fpm-bootstrap" >> $GITHUB_ENV | |
| - name: Build Fortran fpm (bootstrap) | |
| shell: bash | |
| run: | | |
| ${{ env.BOOTSTRAP }} build | |
| - name: Run Fortran fpm (bootstrap) | |
| shell: bash | |
| run: | | |
| ${{ env.BOOTSTRAP }} run | |
| ${{ env.BOOTSTRAP }} run -- --version | |
| ${{ env.BOOTSTRAP }} run -- --help | |
| - name: Test Fortran fpm (bootstrap) | |
| shell: bash | |
| run: | | |
| ${{ env.BOOTSTRAP }} test --flag " -Wno-external-argument-mismatch" | |
| - name: Install Fortran fpm (bootstrap) | |
| shell: bash | |
| run: | | |
| ${{ env.BOOTSTRAP }} install | |
| # Phase 2: Bootstrap fpm with itself | |
| - name: Replace bootstrapping version | |
| shell: bash | |
| run: | | |
| ${{ env.BOOTSTRAP }} run --runner cp -- fpm-debug${{ matrix.exe }} | |
| rm -v ${{ env.BOOTSTRAP }} | |
| echo "FPM=$PWD/fpm-debug" >> $GITHUB_ENV | |
| - name: Get version (normal) | |
| if: github.event_name != 'release' | |
| shell: bash | |
| run: | | |
| VERSION=$(git rev-parse --short HEAD) | |
| echo "VERSION=$VERSION" >> $GITHUB_ENV | |
| - name: Get version (release) | |
| if: github.event_name == 'release' | |
| shell: bash | |
| run: | | |
| VERSION=$(echo ${{ github.ref }} | cut -dv -f2) | |
| echo "VERSION=$VERSION" >> $GITHUB_ENV | |
| FPM_VERSION=$(${{ env.FPM }} --version | grep -o '${{ env.REGEX }}') | |
| [ "$VERSION" = "$FPM_VERSION" ] | |
| env: | |
| REGEX: '[0-9]\{1,4\}\.[0-9]\{1,4\}\.[0-9]\{1,4\}' | |
| - name: Build Fortran fpm | |
| shell: bash | |
| run: | | |
| ${{ env.FPM }} build ${{ matrix.release-flags }} | |
| - name: Run Fortran fpm | |
| shell: bash | |
| run: | | |
| ${{ env.FPM }} run ${{ matrix.release-flags }} | |
| ${{ env.FPM }} run ${{ matrix.release-flags }} -- --version | |
| ${{ env.FPM }} run ${{ matrix.release-flags }} -- --help | |
| - name: Test Fortran fpm | |
| shell: bash | |
| run: | | |
| ${{ env.FPM }} test ${{ matrix.release-flags }} | |
| - name: Install Fortran fpm | |
| shell: bash | |
| run: | | |
| ${{ env.FPM }} install ${{ matrix.release-flags }} | |
| - name: Package release version | |
| shell: bash | |
| run: | | |
| ${{ env.FPM }} run ${{ matrix.release-flags }} --runner cp -- ${{ env.EXE }} | |
| rm -v ${{ env.FPM }} | |
| echo "FPM_RELEASE=${{ env.EXE }}" >> $GITHUB_ENV | |
| env: | |
| EXE: fpm-${{ env.VERSION }}-${{ matrix.os-arch }}-gcc-${{ matrix.toolchain.version }}${{ matrix.exe }} | |
| - name: Run release version | |
| shell: bash | |
| run: | | |
| ci/run_tests.sh "$PWD/${{ env.FPM_RELEASE }}" | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ env.FPM_RELEASE }} | |
| path: ${{ env.FPM_RELEASE }} | |
| make-installer: | |
| if: ${{ github.event_name == 'release' && contains(github.ref, 'v') || github.event_name == 'push' }} | |
| runs-on: windows-latest | |
| needs: | |
| - build | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| gcc_v: [11,12,13] | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Download Artifacts | |
| id: download_windows_artifacts | |
| uses: actions/download-artifact@v5 | |
| with: | |
| path: ${{ github.workspace }} | |
| pattern: fpm-*-windows-*-gcc-${{ matrix.gcc_v }}.exe | |
| - name: Get version (normal) | |
| if: github.event_name != 'release' | |
| shell: bash | |
| run: | | |
| VERSION=$(git rev-parse --short HEAD) | |
| echo "VERSION=$VERSION" >> $GITHUB_ENV | |
| - name: Get version (release) | |
| if: github.event_name == 'release' | |
| shell: bash | |
| run: | | |
| VERSION=$(echo ${{ github.ref }} | cut -dv -f2) | |
| echo "VERSION=$VERSION" >> $GITHUB_ENV | |
| env: | |
| REGEX: '[0-9]\{1,4\}\.[0-9]\{1,4\}\.[0-9]\{1,4\}' | |
| - name: Setup MinGW (MSYS2) | |
| uses: msys2/setup-msys2@v2 | |
| with: | |
| msystem: MINGW64 | |
| update: false | |
| install: >- | |
| wget | |
| unzip | |
| - name: Fetch Windows executable | |
| shell: msys2 {0} | |
| run: | | |
| set -e | |
| download_path='${{ steps.download_windows_artifacts.outputs.download-path }}' | |
| download_path=$(printf '%s\n' "$download_path" | head -n1) | |
| if [ -z "$download_path" ]; then | |
| echo "download-artifact did not report a download path" >&2 | |
| exit 1 | |
| fi | |
| if command -v cygpath >/dev/null 2>&1; then | |
| posix_path=$(cygpath -u "$download_path") | |
| else | |
| posix_path="$download_path" | |
| fi | |
| exe_path=$(find "$posix_path" -maxdepth 2 -type f -name "fpm-*-windows-*-gcc-${{ matrix.gcc_v }}.exe" | head -n 1) | |
| if [ -z "$exe_path" ]; then | |
| echo "Windows executable not found under $posix_path" >&2 | |
| ls -al "$posix_path" || true | |
| exit 1 | |
| fi | |
| cp "$exe_path" ./ci/fpm.exe | |
| - name: Fetch Git for Windows | |
| shell: msys2 {0} | |
| run: | | |
| cd ./ci | |
| wget ${{ env.git_download }} -O MinGit.zip | |
| unzip MinGit.zip -d MinGit | |
| env: | |
| git_download: "https://github.com/git-for-windows/git/releases/download/v2.33.1.windows.1/MinGit-2.33.1-64-bit.zip" | |
| - name: Fetch EnVar Plugin for NSIS | |
| shell: msys2 {0} | |
| run: | | |
| cd ./ci | |
| wget ${{ env.envar_download }} -O EnVar-Plugin.zip | |
| mkdir EnVar_plugin | |
| unzip EnVar-Plugin.zip -d EnVar_plugin | |
| env: | |
| envar_download: "https://github.com/GsNSIS/EnVar/releases/download/v0.3.1/EnVar-Plugin.zip" | |
| - name: Install NSIS | |
| run: choco install nsis -y | |
| shell: pwsh | |
| - name: Add NSIS to PATH | |
| shell: pwsh | |
| run: | | |
| $dirs = @( | |
| "${env:ProgramFiles(x86)}\NSIS", | |
| "${env:ProgramFiles}\NSIS" | |
| ) | Where-Object { $_ -and (Test-Path $_) } | |
| if (-not $dirs) { throw "NSIS not found under Program Files." } | |
| $dirs | ForEach-Object { $_ | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append } | |
| - name: Generate installer | |
| run: | | |
| cd ./ci | |
| makensis fpm-installer.nsi | |
| move fpm-installer.exe fpm-installer-${{ env.VERSION }}-gcc-${{ matrix.gcc_v }}.exe | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: fpm-installer-gcc-${{ matrix.gcc_v }} | |
| path: ci/fpm-installer-${{ env.VERSION }}-gcc-${{ matrix.gcc_v }}.exe | |
| upload-artifacts: | |
| if: ${{ github.event_name == 'release' && contains(github.ref, 'v') || github.event_name == 'push' }} | |
| runs-on: ubuntu-latest | |
| needs: | |
| - build | |
| - make-installer | |
| steps: | |
| - id: deploy-on-push | |
| if: ${{ github.event_name == 'push' }} | |
| run: | |
| echo "::set-output name=result::${{ env.DEPLOY_BRANCH }}" | |
| env: | |
| DEPLOY_BRANCH: ${{ secrets.DEPLOY_BRANCH && contains(github.ref, secrets.DEPLOY_BRANCH) && 1 || 0 }} | |
| - uses: actions/checkout@v5 | |
| if: ${{ github.event_name == 'push' }} | |
| - name: Download Artifacts | |
| uses: actions/download-artifact@v5 | |
| with: | |
| path: fpm-cd-artifacts | |
| pattern: 'fpm-*-gcc-12*' | |
| merge-multiple: true | |
| - name: Normalize file names for continuous delivery | |
| if: ${{ github.event_name == 'push' }} | |
| run: | | |
| cd fpm-cd-artifacts | |
| for output in fpm-*; do | |
| mv -v $(basename $output) $(basename $output | sed -E '${{ env.replace }}') | |
| done | |
| env: | |
| replace: 's/-([0-9]+\.[0-9]+\.[0-9]+-[0-9]+-g)?[0-9a-f]+//' | |
| - name: Create SHA256 checksums | |
| run: | | |
| cd fpm-cd-artifacts | |
| for output in fpm-*; do | |
| sha256sum $(basename "$output") | tee $(basename "$output").sha256 | |
| done | |
| - name: Move/Create continuous tag | |
| if: ${{ github.event_name == 'push' && steps.deploy-on-push.outputs.result != 0 }} | |
| run: | | |
| git tag --force 'current' ${{ github.sha }} | |
| git push --tags --force | |
| - name: Upload assets | |
| uses: svenstaro/upload-release-action@v2 | |
| if: ${{ github.event_name == 'release' || steps.deploy-on-push.outputs.result != 0 }} | |
| with: | |
| repo_token: ${{ secrets.GITHUB_TOKEN }} | |
| file: fpm-cd-artifacts/* | |
| file_glob: true | |
| tag: ${{ github.event_name == 'release' && github.ref || 'current'}} | |
| overwrite: true |