-
Notifications
You must be signed in to change notification settings - Fork 1
132 lines (119 loc) · 5.32 KB
/
Copy pathsplit-app-studio.yaml
File metadata and controls
132 lines (119 loc) · 5.32 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
name: Split app-studio provider
# Publishes providers/app-studio from this monorepo to the standalone,
# read-only mirror at faroshq/provider-app-studio, preserving git history.
#
# Uses splitsh-lite (https://github.com/splitsh/lite) which is deterministic:
# the same source always splits to the same commit sha1s, so pushes normally
# fast-forward. Runs on every push to main (mirrors the branch) and on
# per-provider release tags (see below). workflow_dispatch is provided for the
# initial seed / manual re-sync. It also runs on PRs that touch the split
# surface, but those only validate (install + split) — the deploy-key and push
# steps are gated to non-PR events, so a PR never writes to the mirror.
#
# Releases are tagged per-provider in the monorepo as
# `providers/app-studio/vX.Y.Z`; the prefix is stripped on the way out, so the
# mirror receives a plain `vX.Y.Z` tag (which then triggers its own image/chart
# release workflows). A repo-wide `vX.Y.Z` tag does NOT release the mirror.
#
# Required secret: APP_STUDIO_DEPLOY_KEY
# An SSH private key whose public half is added as a *write* deploy key on
# faroshq/provider-app-studio. (A deploy key is scoped to one repo, so this is
# a distinct key from the other provider mirrors.)
on:
push:
branches: [main]
tags: ['providers/app-studio/v*']
pull_request:
branches: [main]
paths:
- 'providers/app-studio/**'
- '.github/workflows/split-app-studio.yaml'
workflow_dispatch:
permissions:
contents: read
# Serialize splits per ref so two runs never race on the same push to the
# mirror. Do not cancel in-progress runs: a half-completed push is worse than
# waiting.
concurrency:
group: split-app-studio-${{ github.ref }}
cancel-in-progress: false
env:
PREFIX: providers/app-studio
TARGET_REPO: git@github.com:faroshq/provider-app-studio.git
TARGET_BRANCH: main
SPLITSH_VERSION: v1.0.1
jobs:
split:
runs-on: ubuntu-latest
steps:
- name: Checkout (full history)
uses: actions/checkout@v4
with:
# splitsh-lite needs the complete history to compute the split.
fetch-depth: 0
- name: Install splitsh-lite
run: |
set -euo pipefail
mkdir -p "$HOME/.local/bin"
# The v1.0.1 tarball stores the binary as ./splitsh-lite (leading
# ./), so GNU tar won't match a bare `splitsh-lite` member name.
curl -fsSL "https://github.com/splitsh/lite/releases/download/${SPLITSH_VERSION}/lite_linux_amd64.tar.gz" \
| tar -xz -C "$HOME/.local/bin" ./splitsh-lite
chmod +x "$HOME/.local/bin/splitsh-lite"
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
- name: Set up SSH deploy key
if: github.event_name != 'pull_request'
run: |
set -euo pipefail
mkdir -p ~/.ssh
chmod 700 ~/.ssh
install -m 600 /dev/null ~/.ssh/id_split
echo "${{ secrets.APP_STUDIO_DEPLOY_KEY }}" > ~/.ssh/id_split
ssh-keyscan -t rsa,ecdsa,ed25519 github.com >> ~/.ssh/known_hosts 2>/dev/null
cat > ~/.ssh/config <<'EOF'
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_split
IdentitiesOnly yes
EOF
chmod 600 ~/.ssh/config
- name: Compute split
run: |
set -euo pipefail
# Deterministic split of the provider subtree. The resulting commit
# objects are written into the local object store, so they can be
# pushed directly by sha. Runs on every event (incl. PRs) so it
# validates the install + split end-to-end without publishing.
#
# --origin takes a git REF, not a raw commit hash; HEAD is the
# checked-out commit (the pushed tip, or the PR merge commit) and
# resolves cleanly where a bare ${GITHUB_SHA} does not. Capture via a
# file so splitsh-lite's own output isn't swallowed by $(...) on error.
splitsh-lite --prefix="${PREFIX}" --origin=HEAD | tee /tmp/split-sha
SHA="$(tail -n1 /tmp/split-sha)"
[ -n "${SHA}" ] || { echo "split produced no sha"; exit 1; }
echo "Split sha: ${SHA}"
echo "SPLIT_SHA=${SHA}" >> "$GITHUB_ENV"
- name: Push to mirror
if: github.event_name != 'pull_request'
run: |
set -euo pipefail
SHA="${SPLIT_SHA}"
git remote add mirror "${TARGET_REPO}"
if [ "${GITHUB_REF}" != "${GITHUB_REF#refs/tags/}" ]; then
# Per-provider tag: refs/tags/providers/app-studio/vX.Y.Z. Strip the
# path prefix (everything up to the last '/') so the mirror gets a
# plain vX.Y.Z tag.
FULL_TAG="${GITHUB_REF#refs/tags/}"
TAG="${FULL_TAG##*/}"
echo "Publishing tag ${FULL_TAG} -> ${TARGET_REPO} as ${TAG}"
# Tags are immutable; push without force so an accidental re-tag fails loudly.
git push mirror "${SHA}:refs/tags/${TAG}"
else
echo "Publishing branch ${TARGET_BRANCH} -> ${TARGET_REPO}"
# --force keeps the mirror a faithful reflection even if monorepo
# history is ever rewritten. The mirror is read-only, so there are
# no downstream commits to clobber.
git push --force mirror "${SHA}:refs/heads/${TARGET_BRANCH}"
fi