-
Notifications
You must be signed in to change notification settings - Fork 0
173 lines (157 loc) · 6.85 KB
/
Copy pathbuild-repo.yml
File metadata and controls
173 lines (157 loc) · 6.85 KB
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
---
name: Build Pacman Repo
on:
push:
branches: ["main"]
pull_request:
branches: ["main"]
schedule:
- cron: "0 0 * * *"
# On demand: needed after changing the signing secrets, or to re-attempt a
# package that failed under allow-failure, without waiting for the cron or
# inventing a commit.
workflow_dispatch:
permissions:
contents: write
concurrency:
group: "${{ github.workflow }}-${{ github.ref }}"
# Only cancel on pull requests, where the branch churns and a superseded run
# is genuinely worthless. On main this build runs for hours, and cancelling it
# throws away every package it had already compiled -- a commit touching a
# workflow this job does not even read was enough to destroy a run 30 minutes
# in. Queue behind the running build instead.
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
env:
REPO_NAME: custom
RELEASE_TAG: custom-repo
GH_REPO: ${{ github.repository }}
jobs:
build-pacman-repo:
runs-on: ubuntu-latest
# Bound the run. With 70 members, one package that hangs or grinds would
# otherwise consume the 6 hour default and block the nightly build behind
# it. allow-failure contains a build that fails; it cannot contain one that
# never finishes.
timeout-minutes: 300
environment: ${{ github.ref == 'refs/heads/main' && 'prod' || '' }}
steps:
- name: Free Disk Space (Ubuntu)
uses: BRAINSia/free-disk-space@v2
with:
# this might remove tools that are actually needed,
# if set to "true" but frees about 6 GB
tool-cache: false
# all of these default to true, but feel free to set to
# "false" if necessary for your workflow
mandb: true
android: true
dotnet: true
haskell: true
large-packages: true
docker-images: true
# Keep the runner's 4 GB swapfile. Reclaiming it buys a little disk
# but removes the headroom that large C++ builds rely on, and this
# repo's builds were being OOM-killed rather than running out of disk.
swap-storage: false
- name: Checkout Pacman Repo Builder
uses: actions/checkout@v7
with:
repository: pacman-repo-builder/pacman-repo-builder
path: pacman-repo-builder
- name: Checkout yay
uses: nick-fields/retry@v4
with:
timeout_minutes: 10
max_attempts: 3
retry_wait_seconds: 10
command: |
git clone https://aur.archlinux.org/yay.git yay
- name: Checkout this repo
uses: actions/checkout@v7
with:
path: repo
submodules: recursive
- name: Seed the repository state from the release
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
mkdir -p repo-out
# Stamp the moment before reading the database. Anything uploaded to
# the release after this is not represented in what we are about to
# publish, so the prune must leave it alone -- heavy-build spends
# hours with packages uploaded and not yet in the database.
echo "SEED_TIME=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> "$GITHUB_ENV"
# Only the database. build-pacman-repo works out what is outdated from
# it, and repo-add keeps the entries of packages that are not present
# locally, so there is no reason to pull down gigabytes of packages
# that are already published and current.
if gh release view "$RELEASE_TAG" >/dev/null 2>&1; then
for f in "${REPO_NAME}.db.tar.gz" "${REPO_NAME}.files.tar.gz"; do
gh release download "$RELEASE_TAG" --pattern "$f" --dir repo-out --clobber \
|| echo "::warning::no $f published yet"
done
else
echo "Release $RELEASE_TAG does not exist yet; starting from empty."
gh release create "$RELEASE_TAG" --title "custom pacman repo" \
--notes-file repo/.github/release-notes/custom.md
fi
ls -l repo-out/ || true
- name: Run build in Arch Linux container
env:
GPG_SIGNING_KEY: ${{ secrets.GPG_SIGNING_KEY }}
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
run: |
# -e VAR with no value forwards it from the runner environment, so the
# key never appears on the command line where `ps` could read it.
docker run --rm \
-v "${{ github.workspace }}:/workspace" \
-e GITHUB_WORKSPACE=/workspace \
-e GITHUB_OUTPUT=/workspace/.github-output \
-e GPG_SIGNING_KEY \
-e GPG_PASSPHRASE \
-e REPO_NAME \
-w /workspace \
archlinux:base-devel \
bash /workspace/repo/build-inside-container.sh
- name: Re-index anything published while this build ran
if: github.ref == 'refs/heads/main'
env:
GH_TOKEN: ${{ github.token }}
GPG_SIGNING_KEY: ${{ secrets.GPG_SIGNING_KEY }}
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
run: |
set -euo pipefail
# Compare against the release's assets, not against the published
# database. heavy-build publishes into the same release and indexes
# only when its whole matrix finishes, so anything it added while this
# build ran is missing from the copy about to be written -- and once
# one build-repo run has written a database without it, the published
# copy no longer names it either. At that point only the assets still
# say the package exists.
out=$(bash repo/.github/scripts/reindex-orphans.sh \
repo-out "$REPO_NAME" "$RELEASE_TAG" | tee /dev/stderr) || exit 1
if grep -q '^REINDEXED=1$' <<<"$out"; then
# The database changed after the container signed it, so the old
# signature no longer matches -- and pacman rejects a bad database
# signature far more harshly than a missing one.
echo "Database changed; re-signing."
rm -f repo-out/"${REPO_NAME}".db.sig repo-out/"${REPO_NAME}".files.sig \
repo-out/"${REPO_NAME}".db.tar.gz.sig repo-out/"${REPO_NAME}".files.tar.gz.sig
bash repo/.github/scripts/sign-pacman-repo.sh repo-out "$REPO_NAME"
fi
- name: Publish to the release
if: github.ref == 'refs/heads/main'
env:
GH_TOKEN: ${{ github.token }}
run: bash repo/.github/scripts/publish-release-repo.sh repo-out "$REPO_NAME" "$RELEASE_TAG"
- name: Summary
if: always()
run: |
{
echo "### [custom]"
echo
echo '```'
ls -lh repo-out/*.pkg.tar.zst 2>/dev/null | awk '{print $9, $5}' || echo "(none built)"
echo '```'
} >> "$GITHUB_STEP_SUMMARY"