-
Notifications
You must be signed in to change notification settings - Fork 108
133 lines (120 loc) · 5.68 KB
/
build-toolchain-library-and-roms.yml
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
name: Build-Docker
on: [push, pull_request]
# Make sure we don't have more than one active workflow to prevent race conditions
# e.g a previous toolchain build may tag and push `latest` later if we don't have
# this. It is ok to have parallel runs for push and PR events and from different
# branches. We can cancel previous runs for non-trunk events.
concurrency:
group: build-toolchain-library-and-roms-${{ github.ref }}-${{ github.event_name }}
jobs:
Toolchain-Library-And-Examples:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # Using a full fetch so that the diff action can run.
# Create a lower cased version of the repo name. This is required
# because Docker supports only lowercase names in the registry, while
# a repo name on GitHub can have uppercase letters.
- name: Set variables
id: vars
run: |
echo "repository_name=${GITHUB_REPOSITORY,,}" >> $GITHUB_OUTPUT
echo "default_ref=${{ format('refs/heads/{0}', github.event.repository.default_branch) }}" >> $GITHUB_OUTPUT
echo "default_remote=${{ format('refs/remotes/origin/{0}', github.event.repository.default_branch) }}" >> $GITHUB_OUTPUT
- name: Compare files
uses: ./.github/actions/path-diff
id: path_diff
with:
# If it is a push to the default branch, then we should use event.before
# as we cannot just use the default branch ref. Compare to default
# branch otherwise because only the default branch pushes the latest
# image. This assumption may not be true on forks and cause false
# negatives preventing an image build. In that case we might need to
# ask the committer for a fix. OTOH pull requests against the upstream
# repository will always compare against its default branch and cause a
# rebuild, making a valid test run.
base: ${{
(github.event_name == 'push' && (github.ref == steps.vars.outputs.default_ref)) &&
github.event.before ||
steps.vars.outputs.default_remote
}}
head: ${{ github.sha }}
# Build the toolchain if toolchain files changed w.r.t target and we can
# use from registry o/w
- name: Set up Docker Build
if: ${{ steps.path_diff.outputs.changed == 1 }}
uses: docker/setup-buildx-action@v3
- name: Docker meta
if: ${{ steps.path_diff.outputs.changed == 1 }}
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ steps.vars.outputs.repository_name }}
# latest tag is handled separately
flavor: |
latest=false
- name: Log in to the container registry
if: ${{ steps.path_diff.outputs.changed == 1 }}
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push image
if: ${{ steps.path_diff.outputs.changed == 1}}
uses: docker/build-push-action@v5
with:
# Only push image if this is a push event. Otherwise it will fail because
# of permission issues on PRs. Also see https://github.com/DragonMinded/libdragon/issues/230
# In effect, each fork will be releasing its own image to its own
# repository, which we can use to test the toolchain changes.
push: ${{ github.event_name == 'push' }}
tags: ${{ steps.meta.outputs.tags }}
cache-from: type=gha
cache-to: type=gha,mode=max
# In the above build-push-action we did not build a latest tag. Rebuild it
# but do not push it. Instead, load: true will make it available for the
# next build step. It is not possible to do this in a single build-push-action
# because it either pushes it or loads it. As we already have everything
# cached, it should not take long to build.
- name: Load image for libdragon build
if: ${{ steps.path_diff.outputs.changed == 1}}
uses: docker/build-push-action@v5
with:
# Do not push the image yet, we also want to make sure libdragon builds
# with the fresh image.
push: false
load: true
tags: ghcr.io/${{ steps.vars.outputs.repository_name }}:latest
cache-from: type=gha
cache-to: type=gha,mode=max
# As we have a tagged image now, we can use that to run build.sh if it is
# built in the previous step. o/w it will be downloaded from the registry.
# Then verify everything is building properly
- name: Build libdragon
run: |
docker run \
--mount type=bind,source=$(pwd),target=/libdragon \
--workdir=/libdragon \
ghcr.io/${{ steps.vars.outputs.repository_name }}:latest \
./build.sh
- name: "Upload built ROMs to artifacts"
uses: actions/upload-artifact@v4
with:
name: roms
path: |
${{ github.workspace }}/examples/**/*.z64
${{ github.workspace }}/tests/*.z64
# Finally push the verified image to the registry with the latest tag if
# we are on the default branch. At this point, we know that libdragon can
# build with this freshly built image.
- name: Push latest image
if: ${{ steps.path_diff.outputs.changed == 1 && github.ref == steps.vars.outputs.default_ref }}
uses: docker/build-push-action@v5
with:
push: true
tags: ghcr.io/${{ steps.vars.outputs.repository_name }}:latest
cache-from: type=gha
cache-to: type=gha,mode=max