Skip to content

Fold nimble upgrade into nimble lock --refresh #1780

Fold nimble upgrade into nimble lock --refresh

Fold nimble upgrade into nimble lock --refresh #1780

Workflow file for this run

on:
push:
tags:
- "v*" # "v1.2.3"
branches:
- master
paths-ignore: ["nimble-guide/**", "**/*.md"]
pull_request:
paths-ignore: ["nimble-guide/**", "**/*.md"]
workflow_dispatch:
jobs:
build:
strategy:
fail-fast: false
matrix:
target:
# Linux: built natively inside a per-arch musl (Alpine) container run
# under QEMU emulation. No cross toolchain download -- the binary is a
# real, correct-arch, static musl build. `image` is the container base
# (official from-source Nim image where available, so $nim/compiler/*
# resolves), `platform` is the docker --platform, `needsNim` means the
# base image has no Nim so we apk-add it.
- os: linux
triple: x86_64-linux-musl
name: linux_x64
platform: linux/amd64
image: nimlang/nim:2.2.4-alpine
- os: linux
triple: i686-linux-musl
name: linux_x32
platform: linux/386
image: i386/alpine:3.20
needsNim: "1"
- os: linux
triple: aarch64-linux-musl
name: linux_aarch64
platform: linux/arm64
image: nimlang/nim:2.2.4-alpine
- os: linux
triple: armv7l-linux-musleabihf
name: linux_armv7l
platform: linux/arm/v7
image: nimlang/nim:2.2.4-alpine
# macOS: native/cross via clang -target, universal via lipo
- os: macosx
triple: x86_64-apple-darwin14
name: macosx_x64
- os: macosx
triple: aarch64-apple-darwin
name: macosx_aarch64
- os: macosx
triple: universal-apple-darwin
name: macosx_universal
# Windows: single llvm-mingw toolchain targets both arches
- os: windows
triple: x86_64-w64-mingw32
name: windows_x64
nimCpu: amd64
cc: x86_64-w64-mingw32-gcc
- os: windows
triple: i686-w64-mingw32
name: windows_x32
nimCpu: i386
cc: i686-w64-mingw32-gcc
include:
- target:
os: linux
builder: ubuntu-22.04
- target:
os: macosx
builder: macos-14
- target:
os: windows
builder: windows-2025
defaults:
run:
shell: bash
name: "${{ matrix.target.triple }}"
runs-on: ${{ matrix.builder }}
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
submodules: recursive
# Linux builds happen inside a container that already carries Nim, so the
# host Nim toolchain is only set up for macOS/Windows.
- uses: jiro4989/setup-nim-action@v2
if: matrix.target.os != 'linux'
with:
nim-version: "stable"
yes: true
- name: Install dependencies
if: matrix.target.os != 'linux'
run: nimble install -y
- name: Install zip
if: matrix.target.os == 'windows'
run: choco install zip
# A single llvm-mingw toolchain can target every Windows arch (i686,
# x86_64, armv7, arm64) and runs natively on the Windows runner, so it
# fixes windows_x32 (previously built as 64-bit).
- name: Setup llvm-mingw toolchain
if: matrix.target.os == 'windows'
env:
GH_TOKEN: ${{ github.token }}
run: |
set -eu
tag=$(curl -fsSL -H "Authorization: Bearer $GH_TOKEN" \
https://api.github.com/repos/mstorsjo/llvm-mingw/releases/latest \
| grep '"tag_name"' | head -1 | sed -E 's/.*"tag_name": *"([^"]+)".*/\1/')
pkg="llvm-mingw-${tag}-ucrt-x86_64"
curl -fsSL "https://github.com/mstorsjo/llvm-mingw/releases/download/${tag}/${pkg}.zip" -o "$RUNNER_TEMP/llvm-mingw.zip"
unzip -q "$RUNNER_TEMP/llvm-mingw.zip" -d "$RUNNER_TEMP/llvm-mingw"
echo "$RUNNER_TEMP/llvm-mingw/${pkg}/bin" >> "$GITHUB_PATH"
# Register binfmt handlers so non-native (arm64/armv7/i686) containers run.
- name: Set up QEMU
if: matrix.target.os == 'linux'
uses: docker/setup-qemu-action@v3
- name: build nimble (Linux, musl via Alpine container)
if: matrix.target.os == 'linux'
env:
PLATFORM: ${{ matrix.target.platform }}
IMAGE: ${{ matrix.target.image }}
NEEDS_NIM: ${{ matrix.target.needsNim }}
run: |
set -eu
docker run --rm --platform "$PLATFORM" \
-e NEEDS_NIM \
-v "$PWD":/ws -w /ws "$IMAGE" \
sh -euc '
if [ "${NEEDS_NIM:-}" = "1" ]; then
apk add --no-cache nim gcc musl-dev
# apk ships Nim compiler sources as a nimble pkg outside $nim
# (/usr/lib/nim); symlink them in so `import compiler/...` resolves.
compsrc=$(find /usr/share/nimble/pkgs -type f -name nimblecmd.nim -path "*/compiler/*" 2>/dev/null | head -1)
[ -n "$compsrc" ] && ln -sfn "$(dirname "$compsrc")" /usr/lib/nim/compiler
fi
# config.nims wires all vendor/ deps, so no "nimble install" is
# needed. Statically linked -> a portable musl binary.
nim c -d:release --passL:"-static" -o:src/nimble src/nimble.nim
'
- name: build nimble
if: matrix.target.os != 'linux'
env:
TRIPLE: ${{ matrix.target.triple }}
TARGET_OS: ${{ matrix.target.os }}
CC_BIN: ${{ matrix.target.cc }}
NIM_CPU: ${{ matrix.target.nimCpu }}
run: |
set -eu
if [[ "$TRIPLE" == "x86_64-apple-darwin14" ]]; then
nim c -d:release \
-d:zippyNoSimd \
--passL:"-target x86_64-apple-macos10.15" \
--passC:"-target x86_64-apple-macos10.15" \
src/nimble.nim;
elif [[ "$TRIPLE" == "aarch64-apple-darwin" ]]; then
nim c -d:release \
-d:zippyNoSimd \
--passL:"-target arm64-apple-macos11" \
--passC:"-target arm64-apple-macos11" \
src/nimble.nim;
elif [[ "$TRIPLE" == "universal-apple-darwin" ]]; then
nim c -d:release \
-d:zippyNoSimd \
--passL:"-target x86_64-apple-macos10.15" \
--passC:"-target x86_64-apple-macos10.15" \
-o:src/nimble_x64 src/nimble.nim;
nim c -d:release \
-d:zippyNoSimd \
--passL:"-target arm64-apple-macos11" \
--passC:"-target arm64-apple-macos11" \
-o:src/nimble_arm64 src/nimble.nim;
lipo -create src/nimble_x64 src/nimble_arm64 -output src/nimble;
else
# Windows, via llvm-mingw.
nim c -d:release \
--os:windows --cpu:"$NIM_CPU" \
--gcc.exe:"$CC_BIN" --gcc.linkerexe:"$CC_BIN" \
--"$NIM_CPU".windows.gcc.exe:"$CC_BIN" --"$NIM_CPU".windows.gcc.linkerexe:"$CC_BIN" \
--passL:"-static" \
src/nimble.nim;
fi
# Confirm each binary is the architecture it claims to be (the exact check
# from issue #1123). Fails the job loudly if an arch is wrong.
- name: Verify binary architecture
if: matrix.target.os != 'macosx'
env:
TARGET_OS: ${{ matrix.target.os }}
run: |
set -eu
if [[ "$TARGET_OS" == "windows" ]]; then
file src/nimble.exe
else
file src/nimble
fi
- name: Compress binaries
env:
TARGET_OS: ${{ matrix.target.os }}
ASSET: ${{ matrix.target.name }}
run: |
cd src
if [[ "$TARGET_OS" == "windows" ]]; then
# Create both formats for Windows
tar -c -z -v -f "../nimble-${ASSET}.tar.gz" nimble.exe
zip "../nimble-${ASSET}.zip" nimble.exe
else
tar -c -z -v -f "../nimble-${ASSET}.tar.gz" nimble
fi
- name: Upload tar.gz artifact
uses: actions/upload-artifact@v7
with:
name: nimble-${{ matrix.target.name }}.tar.gz
path: nimble-${{ matrix.target.name }}.tar.gz
- name: Upload zip artifact (Windows only)
if: matrix.target.os == 'windows'
uses: actions/upload-artifact@v7
with:
name: nimble-${{ matrix.target.name }}.zip
path: nimble-${{ matrix.target.name }}.zip
create-github-release:
if: github.event_name != 'pull_request'
name: Create GitHub Release
needs: [build]
runs-on: ubuntu-latest
permissions:
contents: write
actions: write
steps:
- name: Download artefacts
uses: actions/download-artifact@v8
# Create/update the "latest" release
- uses: ncipollo/release-action@v1
with:
name: Latest Nimble Binaries
artifacts: "*/*"
allowUpdates: true
makeLatest: true
prerelease: true
tag: latest
# Generate release notes and create a versioned release if this is a tag push
- if: startsWith(github.ref, 'refs/tags/v')
name: Generate release notes
id: release_notes
uses: actions/github-script@v8
with:
script: |
const { data: releaseNotes } = await github.rest.repos.generateReleaseNotes({
owner: context.repo.owner,
repo: context.repo.repo,
tag_name: context.ref.replace('refs/tags/', ''),
target_commitish: context.sha,
});
core.setOutput('notes', releaseNotes.body)
- if: startsWith(github.ref, 'refs/tags/v')
uses: ncipollo/release-action@v1
with:
name: Nimble ${{ github.ref_name }}
artifacts: "*/*"
allowUpdates: true
makeLatest: false
prerelease: false
draft: true
tag: ${{ github.ref_name }}
body: ${{ steps.release_notes.outputs.notes }}
- name: Delete artefacts
uses: geekyeggo/delete-artifact@v6
with:
token: ${{ secrets.GITHUB_TOKEN }}
failOnError: false
name: "nimble-*"