-
Notifications
You must be signed in to change notification settings - Fork 0
170 lines (147 loc) · 6.31 KB
/
Copy pathsync_template.yml
File metadata and controls
170 lines (147 loc) · 6.31 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
name: Sync with Template Repository
on:
schedule:
# Run weekly on Monday at 9 AM UTC
- cron: '0 9 * * 1'
workflow_dispatch:
# This enables only one template synchronization workflow at a time.
concurrency:
group: template-sync-main
cancel-in-progress: false
permissions:
contents: write
pull-requests: write
jobs:
sync-template:
name: Sync with template repository
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: main
fetch-depth: 0
# Do not leave the default GITHUB_TOKEN in the local Git configuration.
# The pull-request step authenticates separately with the repository-scoped
# LABCONSTRICTOR_SYNC_TOKEN secret.
persist-credentials: false
- name: Configure Git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Add upstream remote
run: |
git remote add upstream https://github.com/CellMigrationLab/LabConstrictor.git
- name: Fetch upstream changes
run: |
git fetch upstream main
- name: Read local template version
id: local-version
run: |
local_version=$(python3 - <<'PY'
from pathlib import Path
manifest = Path(".template_sync/manifest.yaml")
if not manifest.exists():
print("0.0.0")
raise SystemExit
for line in manifest.read_text(encoding="utf-8").splitlines():
stripped = line.strip()
if stripped.startswith("template_version:"):
print(stripped.split(":", 1)[1].strip())
break
else:
raise SystemExit("template_version not found in .template_sync/manifest.yaml")
PY
)
echo "version=$local_version" >> "$GITHUB_OUTPUT"
- name: Read upstream template version
id: upstream-version
run: |
upstream_version=$(python3 - <<'PY'
import subprocess
manifest = subprocess.run(
["git", "show", "upstream/main:.template_sync/manifest.yaml"],
check=True,
capture_output=True,
text=True,
).stdout
for line in manifest.splitlines():
stripped = line.strip()
if stripped.startswith("template_version:"):
print(stripped.split(":", 1)[1].strip())
break
else:
raise SystemExit(
"template_version not found in upstream .template_sync/manifest.yaml"
)
PY
)
echo "version=$upstream_version" >> "$GITHUB_OUTPUT"
- name: Check whether template sync is needed
id: version-check
env:
LOCAL_VERSION: ${{ steps.local-version.outputs.version }}
UPSTREAM_VERSION: ${{ steps.upstream-version.outputs.version }}
run: |
python3 - <<'PY'
import os
from pathlib import Path
def parse_version(version: str) -> tuple[int, ...]:
return tuple(int(part) for part in version.split("."))
local_version = os.environ["LOCAL_VERSION"]
upstream_version = os.environ["UPSTREAM_VERSION"]
sync_required = parse_version(upstream_version) > parse_version(local_version)
output_path = Path(os.environ["GITHUB_OUTPUT"])
with output_path.open("a", encoding="utf-8") as fh:
fh.write(f"sync_required={'true' if sync_required else 'false'}\n")
PY
- name: Check synchronization token setup
if: steps.version-check.outputs.sync_required == 'true'
env:
LABCONSTRICTOR_SYNC_TOKEN: ${{ secrets.LABCONSTRICTOR_SYNC_TOKEN }}
run: |
if [[ -z "$LABCONSTRICTOR_SYNC_TOKEN" ]]; then
{
echo "## One-time LabConstrictor setup required"
echo
echo "A template update is available, but this repository does not have the"
echo '`LABCONSTRICTOR_SYNC_TOKEN` repository secret configured.'
echo
echo "Follow the beginner-friendly guide in:"
echo
echo '`.tools/docs/template_synchronization.md`'
} >> "$GITHUB_STEP_SUMMARY"
echo "::error title=Synchronization setup required::Configure the LABCONSTRICTOR_SYNC_TOKEN repository secret by following .tools/docs/template_synchronization.md."
exit 1
fi
- name: Fetch template sync bootstrap
if: steps.version-check.outputs.sync_required == 'true'
run: |
git checkout upstream/main -- .template_sync
- name: Run template migrations
if: steps.version-check.outputs.sync_required == 'true'
run: |
python3 .template_sync/sync.py \
--from-version "${{ steps.local-version.outputs.version }}" \
--to-version "${{ steps.upstream-version.outputs.version }}" \
--repository-root "$GITHUB_WORKSPACE"
- name: Check for changes
id: check-changes
run: |
if [[ -n "$(git status --short)" ]]; then
echo "has_changes=true" >> "$GITHUB_OUTPUT"
else
echo "has_changes=false" >> "$GITHUB_OUTPUT"
fi
- name: Create pull request
if: steps.check-changes.outputs.has_changes == 'true'
uses: peter-evans/create-pull-request@v6
with:
token: ${{ secrets.LABCONSTRICTOR_SYNC_TOKEN }}
branch: template-sync-${{ steps.local-version.outputs.version }}-to-${{ steps.upstream-version.outputs.version }}
delete-branch: true
commit-message: Sync template to version ${{ steps.upstream-version.outputs.version }}
title: Sync template to version ${{ steps.upstream-version.outputs.version }}
body: |
This PR updates `.template_sync` from the template repository and applies the migrations needed to move this repository from template version `${{ steps.local-version.outputs.version }}` to `${{ steps.upstream-version.outputs.version }}`.
The branch is created with the repository-scoped `LABCONSTRICTOR_SYNC_TOKEN` secret so that updates to GitHub workflow files can be included safely.