summaryrefslogtreecommitdiff
path: root/.github/workflows/ci_cortex_m.yml
blob: 933c950fbf1833c8c7ac7b4c75f45efbb165b74a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
name: cortex_m

# Cross-compiles the Cortex-M ports with GCC.
#
# Two things were wrong with this workflow and both are fixed here.
#
# It ran on master only, for both push and pull_request, while dev is the
# integration branch -- the same defect ports_arch_check.yml carries a comment
# about, where it cost eight months of ports drifting unnoticed. So this
# gated no pull request that anybody opened.
#
# And it had not compiled anything since at least 2026-06-08. Every run since
# then failed in six to eight seconds, at "Prepare all required actions",
# before checkout: GitHub automatically fails any request using
# actions/cache@v1. Nobody noticed, because of the first defect.
#
# The toolchain setup now follows clang_check.yml rather than third party
# actions: a pinned release fetched directly, verified against Arm's published
# checksum, and cached with actions/cache@v4. That also moves the compiler
# from 9-2019-q4 to a version matching the project's stated GCC 14 default.
#
# This covers four ports of the forty under ports/ that have a gnu directory.
# Widening that to every Arm gnu port is separate work.
on:
  push:
    branches: [ master, dev ]
  pull_request:
    branches: [ master, dev ]
    paths:
      - ".github/workflows/ci_cortex_m.yml"
      - 'common/**'
      - 'utility/**'
      - 'ports/cortex_m0/gnu/**'
      - 'ports/cortex_m3/gnu/**'
      - 'ports/cortex_m4/gnu/**'
      - 'ports/cortex_m7/gnu/**'

jobs:
  build:
    runs-on: ubuntu-24.04

    strategy:
      fail-fast: false
      matrix:
        port: [0, 3, 4, 7]

    name: Cortex M${{ matrix.port }} build

    env:
      # Pinned deliberately, as the runner image is: a toolchain upgrade should
      # be a reviewable commit rather than something that changes underneath the
      # ports. Releases: https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads
      GCC_VERSION: 14.3.rel1
      GCC_TARGET: arm-none-eabi

    steps:
    # Actions are pinned to a commit SHA, with the version in the trailing
    # comment. A tag can be moved; a SHA cannot, so this is what makes "which
    # code ran in CI" answerable from the repository. Dependabot moves these
    # pins and rewrites the comment with them -- see .github/dependabot.yml.
    - name: Check out the repository
      uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
      with:
        submodules: true

    - name: Cache the Arm GNU toolchain
      id: cache-arm-gcc
      uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
      with:
        path: toolchain
        key: arm-gnu-toolchain-${{ env.GCC_VERSION }}-x86_64-${{ env.GCC_TARGET }}

    - name: Install the Arm GNU toolchain
      if: steps.cache-arm-gcc.outputs.cache-hit != 'true'
      run: |
        set -eu
        base="https://developer.arm.com/-/media/Files/downloads/gnu/${GCC_VERSION}/binrel"
        archive="arm-gnu-toolchain-${GCC_VERSION}-x86_64-${GCC_TARGET}.tar.xz"
        mkdir -p toolchain && cd toolchain
        curl -fsSLO "$base/$archive"
        curl -fsSLO "$base/$archive.sha256asc"
        sha256sum -c "$archive.sha256asc"
        tar xf "$archive"
        rm -f "$archive"

    - name: Put the toolchain on PATH
      run: |
        set -eu
        echo "$GITHUB_WORKSPACE/toolchain/arm-gnu-toolchain-${GCC_VERSION}-x86_64-${GCC_TARGET}/bin" >> "$GITHUB_PATH"

    # Only reaches apt if the runner image has stopped shipping ninja. This
    # repository has already paid for unguarded apt calls: scripts/install.sh
    # carries a long comment about apt-get update stalling for over two hours
    # and taking whole regression runs with it. Do not turn this into an
    # unconditional install.
    - name: Ensure ninja is available
      run: |
        set -eu
        if command -v ninja >/dev/null 2>&1; then
          ninja --version
        else
          sudo apt-get update
          sudo apt-get install -y --no-install-recommends ninja-build
        fi

    - name: Report the toolchain version
      run: ${{ env.GCC_TARGET }}-gcc --version

    - name: Prepare build system
      run: cmake -Bbuild -DCMAKE_TOOLCHAIN_FILE=./cmake/cortex_m${{ matrix.port }}.cmake -GNinja .

    - name: Compile and link
      run: cmake --build ./build