sync.yml RawHistoryFolder
1name: sync
2
3on:
4 schedule:
5 - cron: '30 4 * * *'
6 workflow_dispatch:
7
8permissions:
9 contents: read
10
11concurrency:
12 group: sync
13 cancel-in-progress: false
14
15jobs:
16 # prepare runs all third-party code (go modules, staticcheck, tests) with a
17 # read-only token and hands the result over as a patch.
18 prepare:
19 runs-on: ubuntu-latest
20 permissions:
21 contents: read
22 outputs:
23 changed: ${{ steps.sync.outputs.changed }}
24 steps:
25 - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
26 with:
27 persist-credentials: false
28 - uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5
29 with:
30 go-version-file: go.mod
31 - name: Install Wayland libraries
32 run: sudo apt-get update && sudo apt-get install -y --no-install-recommends libwayland-server0 libwayland-client0 wayland-utils
33 - name: Sync upstream protocols
34 id: sync
35 run: |
36 mkdir -p "$RUNNER_TEMP/out"
37 result="$(go run ./cmd/wlbsync -notes "$RUNNER_TEMP/out/notes.md")"
38 echo "$result"
39 printf '%s\n' "$result" | grep -E '^changed=(true|false)$' >> "$GITHUB_OUTPUT"
40 - name: Generate
41 if: steps.sync.outputs.changed == 'true'
42 run: go generate ./...
43 - name: Vet
44 if: steps.sync.outputs.changed == 'true'
45 run: go vet ./...
46 - name: Staticcheck
47 if: steps.sync.outputs.changed == 'true'
48 run: go run honnef.co/go/tools/cmd/staticcheck@2026.2.1 ./...
49 - name: Test (CGO disabled)
50 if: steps.sync.outputs.changed == 'true'
51 run: CGO_ENABLED=0 go test ./...
52 - name: Test (race)
53 if: steps.sync.outputs.changed == 'true'
54 run: go test -race ./...
55 - name: Create patch
56 env:
57 CHANGED: ${{ steps.sync.outputs.changed }}
58 run: |
59 : > "$RUNNER_TEMP/out/changes.patch"
60 if [ "$CHANGED" = 'true' ]; then
61 git add -A
62 git diff --cached --binary > "$RUNNER_TEMP/out/changes.patch"
63 test -s "$RUNNER_TEMP/out/changes.patch"
64 fi
65 - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
66 with:
67 name: sync
68 path: ${{ runner.temp }}/out
69 if-no-files-found: error
70 retention-days: 1
71
72 # publish has write access and runs no third-party code: it applies the
73 # patch, commits through the API and cuts the release.
74 publish:
75 needs: prepare
76 if: github.ref == 'refs/heads/main'
77 runs-on: ubuntu-latest
78 permissions:
79 contents: write
80 steps:
81 - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
82 with:
83 fetch-depth: 0
84 persist-credentials: false
85 - uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5
86 with:
87 go-version-file: go.mod
88 cache: false
89 - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
90 with:
91 name: sync
92 path: ${{ runner.temp }}/sync
93 - name: Apply patch
94 if: needs.prepare.outputs.changed == 'true'
95 run: |
96 test -s "$RUNNER_TEMP/sync/changes.patch"
97 git apply --index "$RUNNER_TEMP/sync/changes.patch"
98 - name: Commit via GitHub API
99 id: commit
100 if: needs.prepare.outputs.changed == 'true'
101 env:
102 GITHUB_TOKEN: ${{ github.token }}
103 run: |
104 message="$(printf 'feat(spec): sync upstream protocols\n\n'; head -n 20 "$RUNNER_TEMP/sync/notes.md")"
105 sha="$(go run ./cmd/wlbcommit -repo "$GITHUB_REPOSITORY" -branch main -message "$message")"
106 echo "commit: $sha"
107 echo "sha=$sha" >> "$GITHUB_OUTPUT"
108 - name: Release
109 id: release
110 if: success()
111 env:
112 GH_TOKEN: ${{ github.token }}
113 COMMITTED_SHA: ${{ steps.commit.outputs.sha }}
114 run: |
115 set -euo pipefail
116 if [ -n "$COMMITTED_SHA" ]; then
117 target="$COMMITTED_SHA"
118 auth="$(printf 'x-access-token:%s' "$GH_TOKEN" | base64 -w0)"
119 GIT_CONFIG_COUNT=1 \
120 GIT_CONFIG_KEY_0="http.https://github.com/.extraheader" \
121 GIT_CONFIG_VALUE_0="AUTHORIZATION: basic $auth" \
122 git fetch --no-tags origin main
123 git cat-file -e "$target^{commit}"
124 else
125 target="$(git rev-parse HEAD)"
126 fi
127 echo "release target: $target"
128
129 # Already released?
130 if git tag --points-at "$target" | grep -qE '^v0\.[0-9]+\.[0-9]+$'; then
131 echo "$target is already tagged; nothing to release"
132 exit 0
133 fi
134
135 latest="$(git tag -l 'v0.*' --sort=-v:refname | grep -E '^v0\.[0-9]+\.[0-9]+$' | sed -n 1p || true)"
136 if [ -z "$latest" ]; then
137 # The first release is a maintainer-signed tag; automation only
138 # continues an existing v0 series.
139 echo "no v0 tag yet; create the first release manually"
140 exit 0
141 else
142 rc=0
143 git diff --quiet "$latest" "$target" -- spec/xml client server || rc=$?
144 case "$rc" in
145 0) echo "no changes in spec/xml, client, server since $latest; nothing to release"; exit 0 ;;
146 1) ;;
147 *) echo "git diff failed ($rc)" >&2; exit "$rc" ;;
148 esac
149 minor="${latest#v0.}"
150 minor="${minor%%.*}"
151 tag="v0.$((minor + 1)).0"
152 fi
153 echo "latest tag: ${latest:-none}; next tag: $tag"
154
155 if [ -n "$COMMITTED_SHA" ]; then
156 gh release create "$tag" --target "$target" --title "$tag" --notes-file "$RUNNER_TEMP/sync/notes.md"
157 else
158 gh release create "$tag" --target "$target" --title "$tag" --generate-notes
159 fi
160 echo "tag=$tag" >> "$GITHUB_OUTPUT"
161 - name: Warm Go module proxy
162 if: steps.release.outputs.tag != ''
163 env:
164 TAG: ${{ steps.release.outputs.tag }}
165 run: |
166 curl -fsS "https://proxy.golang.org/github.com/bnema/go-wayland-bindings/@v/$TAG.info" || true