;doc: PULLREQUESTS: guidance on PR titles #1
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
| # TRIGGER: Runs on any push to binaries-linux-arm64-stack or binaries branches. | ||
| # ACTION: Builds, unit-tests and saves linux arm64 static binaries with stack and the resolver & ghc version below, | ||
| # in an Alpine linux container which provides the statically-linkable musl. | ||
| name: binaries-linux-arm64-stack | ||
| on: | ||
| push: | ||
| branches: [ binaries-linux-arm64-stack ] | ||
| workflow_dispatch: | ||
| jobs: | ||
| build: | ||
| runs-on: ubuntu-latest | ||
| container: alpine:latest | ||
| steps: | ||
| - name: Show platform info | ||
| run: | | ||
| arch | ||
| uname -a | ||
| - name: Check out | ||
| uses: actions/checkout@v4 | ||
| # have to fetch everything for git describe for --version | ||
| with: | ||
| fetch-depth: 0 | ||
| # - name: Check embedded files | ||
| # run: | | ||
| # apt install ripgrep | ||
| # tools/checkembeddedfiles | ||
| # things to be cached/restored: | ||
| # - name: Cache: ghcup-installed tools | ||
| # id: ghcup | ||
| # uses: actions/cache@v4 | ||
| # with: | ||
| # path: ~/.ghcup | ||
| # key: ${{ runner.os }}-ghcup-${{ hashFiles('**.yaml') }} | ||
| # restore-keys: | | ||
| # ${{ runner.os }}-ghcup | ||
| - name: Cache: stack-installed programs in ~/.local/bin | ||
| id: stack-programs | ||
| uses: actions/cache@v4 | ||
| with: | ||
| path: ~/.local/bin | ||
| key: ${{ runner.os }}-aarch64-stack-programs-${{ hashFiles('**.yaml') }} | ||
| restore-keys: | | ||
| ${{ runner.os }}-aarch64-stack-programs | ||
| - name: Cache: stack global package db | ||
| id: stack-global | ||
| uses: actions/cache@v4 | ||
| with: | ||
| path: ~/.stack | ||
| key: ${{ runner.os }}-aarch64-stack-global-${{ hashFiles('**.yaml') }} | ||
| restore-keys: | | ||
| ${{ runner.os }}-aarch64-stack-global | ||
| - name: Cache: .stack-work | ||
| uses: actions/cache@v4 | ||
| with: | ||
| path: .stack-work | ||
| key: ${{ runner.os }}-aarch64-stack-work-${{ hashFiles('**.yaml') }} | ||
| restore-keys: | | ||
| ${{ runner.os }}-aarch64-stack-work | ||
| - name: Cache: hledger-lib/.stack-work | ||
| uses: actions/cache@v4 | ||
| with: | ||
| path: hledger-lib/.stack-work | ||
| key: ${{ runner.os }}-aarch64-hledger-lib-stack-work-${{ hashFiles('hledger-lib/package.yaml') }} | ||
| restore-keys: | | ||
| ${{ runner.os }}-aarch64-hledger-lib-stack-work | ||
| - name: Cache: hledger/.stack-work | ||
| uses: actions/cache@v4 | ||
| with: | ||
| path: hledger/.stack-work | ||
| key: ${{ runner.os }}-aarch64-hledger-stack-work-${{ hashFiles('hledger/package.yaml') }} | ||
| restore-keys: | | ||
| ${{ runner.os }}-aarch64-hledger-stack-work | ||
| - name: Cache: hledger-ui/.stack-work | ||
| uses: actions/cache@v4 | ||
| with: | ||
| path: hledger-ui/.stack-work | ||
| key: ${{ runner.os }}-aarch64-hledger-ui-stack-work-${{ hashFiles('hledger-ui/package.yaml') }} | ||
| restore-keys: | | ||
| ${{ runner.os }}-aarch64-hledger-ui-stack-work | ||
| - name: Cache: hledger-web/.stack-work | ||
| uses: actions/cache@v4 | ||
| with: | ||
| path: hledger-web/.stack-work | ||
| key: ${{ runner.os }}-aarch64-hledger-web-stack-work-${{ hashFiles('hledger-web/package.yaml') }} | ||
| restore-keys: | | ||
| ${{ runner.os }}-aarch64-hledger-web-stack-work | ||
| # actions: | ||
| # - name: Install general tools with system package manager | ||
| # run: | | ||
| # apk --no-cache add binutils-gold curl gcc g++ git ripgrep tar gmp-dev libffi-dev ncurses-dev ncurses-static zlib-dev zlib-static | ||
| # set HOME to /root for stack (do it here in case it matters for ghcup too). workaround from https://github.com/actions/runner/issues/863) | ||
| - name: Set $HOME to /root for stack | ||
| run: | | ||
| apk add sudo | ||
| echo "setting HOME=/root for stack" | ||
| echo HOME=/root | sudo tee -a $GITHUB_ENV | ||
| - name: Install System Dependencies | ||
| run: | | ||
| # Add dependencies GHC/Stack need for linking | ||
| apk add stack gmp-dev zlib-dev zlib-static libffi-dev ncurses-dev ncurses-static gcc make musl-dev xz ripgrep | ||
| - name: Configure stack.yaml for static linking | ||
| run: | | ||
| # Add the ghc-options section to stack.yaml, using "$all" | ||
| echo "ghc-options:" >> stack.yaml | ||
| echo ' "$all": -fPIC -static -pie -Werror' >> stack.yaml | ||
| echo "Applied new stack.yaml configuration:" | ||
| cat stack.yaml | ||
| # - name: Install haskell tools if needed | ||
| # run: | | ||
| # Try hard to persuade ghcup to install an aarch64 binary | ||
| #ghcup config set platform-override '{ "arch": "A_64", "platform": { "contents": "Alpine", "tag": "Linux" }, "version": "3.18" }' | ||
| # cat >~/.ghcup/config.yaml <<END | ||
| # platform-override: | ||
| # arch: A_64 | ||
| # platform: | ||
| # contents: Alpine | ||
| # tag: Linux | ||
| # version: '3.18' | ||
| # END | ||
| # if [[ ! -x ~/.ghcup/bin/ghc-9.12.2 ]]; then ~/.ghcup/bin/ghcup install ghc 9.12.2 -u https://downloads.haskell.org/~ghc/9.12.2/ghc-9.12.2-aarch64-alpine3_18-linux.tar.xz && ~/.ghcup/bin/ghcup set ghc 9.12.2; fi; printf "ghc: "; ghc --version | ||
| # if [[ ! -x ~/.ghcup/bin/cabal ]]; then ~/.ghcup/bin/ghcup install cabal 3.14.2.0 && ~/.ghcup/bin/ghcup set cabal 3.14.2.0; fi; printf "cabal: "; cabal --version | ||
| # curl -sSL https://get.haskellstack.org/ | sh | ||
| # # cat > ~/.stack/global-project/stack.yaml << END | ||
| # # packages: [] | ||
| # # resolver: nightly-2025-05-01 | ||
| # # compiler: ghc-9.12.2 | ||
| # # notify-if-ghc-untested: false | ||
| # # notify-if-cabal-untested: false | ||
| # # END | ||
| # stack --allow-different-user setup --install-ghc | ||
| # --allow-different-user is needed because of #863 above (or because stack didn't notice we're in a docker container) | ||
| - name: List dep versions | ||
| run: | | ||
| stack exec -- ghc-pkg list | ||
| - name: Build with stack and run unit tests | ||
| run: | | ||
| # stack --allow-different-user build --test --ghc-options='-fPIC -optl-static -Werror' hledger # || (echo "ERROR: building hledger failed"; false) | ||
| # stack --allow-different-user build --test --ghc-options='-fPIC -optl-static -Werror' hledger-ui # || (echo "ERROR: building hledger-ui failed"; false) | ||
| # stack --allow-different-user build --test --ghc-options='-fPIC -optl-static -Werror' hledger-web # || (echo "ERROR: building hledger-web failed"; false) | ||
| stack --allow-different-user install --test --ghc-options='-Werror' hledger # || (echo "ERROR: building hledger failed"; false) | ||
| # stack --allow-different-user install --test --ghc-options='-Werror' hledger-ui # || (echo "ERROR: building hledger-ui failed"; false) | ||
| # stack --allow-different-user install --test --ghc-options='-Werror' hledger-web # || (echo "ERROR: building hledger-web failed"; false) | ||
| # - name: Build static hledger binary | ||
| # run: | | ||
| # # --allow-different-user is needed because you are root in the container | ||
| # # It's good practice to clean after a major flag change. | ||
| # # stack --allow-different-user clean | ||
| # stack --allow-different-user build --test | ||
| - name: Verify the binary | ||
| run: | | ||
| # Find the built executable and check if it's a static binary | ||
| BINARY_PATH=$(stack --allow-different-user exec -- which hledger) | ||
| echo "Binary is at: $BINARY_PATH" | ||
| echo "Checking linkage:" | ||
| # The output of ldd should be "statically linked" or "not a dynamic executable" | ||
| ldd "$BINARY_PATH" | ||
| - name: Gather binaries | ||
| run: | | ||
| mkdir tmp | ||
| cp ~/.local/bin/hledger tmp | ||
| cp ~/.local/bin/hledger-ui tmp | ||
| cp ~/.local/bin/hledger-web tmp | ||
| cp hledger/embeddedfiles/*.1 tmp | ||
| cp hledger/embeddedfiles/*.info tmp | ||
| cp hledger/shell-completion/hledger-completion.bash tmp | ||
| strip tmp/hledger | ||
| strip tmp/hledger-ui | ||
| strip tmp/hledger-web | ||
| cd tmp | ||
| tar cvf hledger-linux-arm64.tar hledger hledger-ui hledger-web *.1 *.info hledger-completion.bash | ||
| ./hledger --version | ||
| ./hledger-ui --version | ||
| ./hledger-web --version | ||
| # upload-artifact loses execute permissions, so we tar the binaries to preserve them. | ||
| # github UI always zips artifacts when they are downloaded, so we don't bother compressing the tar. | ||
| # Unfortunately it means users must both unzip and untar. | ||
| - name: Upload binaries | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: hledger-linux-arm64 | ||
| path: tmp/hledger-linux-arm64.tar | ||