Skip to content

Commit 5cfcbdf

Browse files
feat(ci): per-artifact build system foundation (pr-build + release workflows)
feat(ci): per-artifact build system foundation (pr-build + release workflows)
2 parents bc7db9b + 4f398f5 commit 5cfcbdf

423 files changed

Lines changed: 15509 additions & 18098 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
name: Setup Toolchain
2+
description: |
3+
Loads sdk/runanywhere-commons/VERSIONS into $GITHUB_ENV and installs the
4+
per-platform toolchain (Xcode, NDK, JDK, Node, Emscripten, CMake) at the
5+
versions pinned in VERSIONS. Single source of truth for tool versions.
6+
7+
inputs:
8+
platform:
9+
required: true
10+
description: 'ios | macos | android | linux | windows | web | sdk-only'
11+
12+
runs:
13+
using: composite
14+
steps:
15+
# ----------------------------------------------------------------------
16+
# 1. Load VERSIONS into $GITHUB_ENV so subsequent steps see the values.
17+
# ----------------------------------------------------------------------
18+
- name: Load VERSIONS into env
19+
shell: bash
20+
run: |
21+
set -euo pipefail
22+
VERSIONS_FILE="${GITHUB_WORKSPACE}/sdk/runanywhere-commons/VERSIONS"
23+
if [ ! -f "$VERSIONS_FILE" ]; then
24+
echo "::error::VERSIONS file not found at $VERSIONS_FILE"
25+
exit 1
26+
fi
27+
# Strip comments + blank lines, keep KEY=VALUE only
28+
grep -E '^[A-Z_][A-Z0-9_]*=' "$VERSIONS_FILE" | while IFS='=' read -r k v; do
29+
# Trim surrounding whitespace (xargs handles this)
30+
k="$(echo "$k" | xargs)"
31+
v="$(echo "$v" | xargs)"
32+
echo "$k=$v" >> "$GITHUB_ENV"
33+
done
34+
echo "::group::Loaded versions"
35+
cat "$VERSIONS_FILE" | grep -E '^[A-Z_][A-Z0-9_]*='
36+
echo "::endgroup::"
37+
38+
# ----------------------------------------------------------------------
39+
# 2. Per-platform toolchain installation (uses env vars from step 1).
40+
# ----------------------------------------------------------------------
41+
- name: Setup Xcode (iOS/macOS)
42+
if: inputs.platform == 'ios' || inputs.platform == 'macos'
43+
uses: maxim-lobanov/setup-xcode@v1
44+
with:
45+
xcode-version: ${{ env.XCODE_VERSION }}
46+
47+
- name: Setup JDK (Android/SDK)
48+
if: inputs.platform == 'android' || inputs.platform == 'sdk-only'
49+
uses: actions/setup-java@v4
50+
with:
51+
distribution: temurin
52+
java-version: ${{ env.JAVA_VERSION }}
53+
54+
- name: Setup Android SDK + NDK (Android)
55+
if: inputs.platform == 'android'
56+
uses: android-actions/setup-android@v3
57+
58+
- name: Install pinned Android NDK
59+
if: inputs.platform == 'android'
60+
shell: bash
61+
run: |
62+
set -euo pipefail
63+
echo "y" | sdkmanager --install "ndk;${NDK_VERSION}" >/dev/null
64+
echo "ANDROID_NDK_HOME=${ANDROID_HOME}/ndk/${NDK_VERSION}" >> "$GITHUB_ENV"
65+
echo "ANDROID_NDK_ROOT=${ANDROID_HOME}/ndk/${NDK_VERSION}" >> "$GITHUB_ENV"
66+
67+
- name: Setup Node (Web/RN/SDK)
68+
if: inputs.platform == 'web' || inputs.platform == 'sdk-only'
69+
uses: actions/setup-node@v4
70+
with:
71+
node-version: ${{ env.NODE_VERSION }}
72+
73+
- name: Setup Emscripten (Web)
74+
if: inputs.platform == 'web'
75+
uses: mymindstorm/setup-emsdk@v14
76+
with:
77+
version: ${{ env.EMSCRIPTEN_VERSION }}
78+
actions-cache-folder: emsdk-cache
79+
80+
- name: Setup CMake (Linux/Windows native)
81+
if: inputs.platform == 'linux' || inputs.platform == 'windows'
82+
uses: jwlawson/actions-setup-cmake@v2
83+
with:
84+
cmake-version: ${{ env.CMAKE_VERSION }}
85+
86+
- name: Install Linux build deps
87+
if: inputs.platform == 'linux'
88+
shell: bash
89+
run: |
90+
sudo apt-get update -qq
91+
sudo apt-get install -y --no-install-recommends \
92+
build-essential ninja-build pkg-config
93+
94+
- name: Print toolchain summary
95+
shell: bash
96+
run: |
97+
echo "::group::Toolchain summary for platform=${{ inputs.platform }}"
98+
command -v xcodebuild >/dev/null 2>&1 && xcodebuild -version || true
99+
command -v javac >/dev/null 2>&1 && javac -version || true
100+
command -v node >/dev/null 2>&1 && node --version || true
101+
command -v emcc >/dev/null 2>&1 && emcc --version | head -1 || true
102+
command -v cmake >/dev/null 2>&1 && cmake --version | head -1 || true
103+
echo "ANDROID_NDK_HOME=${ANDROID_NDK_HOME:-unset}"
104+
echo "::endgroup::"

.github/workflows/auto-tag.yml

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
name: Auto-Tag Release
2+
3+
# =============================================================================
4+
# Label-driven release triggering.
5+
#
6+
# When a PR is merged to main with one of these labels:
7+
# release:patch — v0.19.7 → v0.19.8
8+
# release:minor — v0.19.7 → v0.20.0
9+
# release:major — v0.19.7 → v1.0.0
10+
#
11+
# this workflow:
12+
# 1. Determines the current PROJECT_VERSION from sdk/runanywhere-commons/VERSIONS
13+
# 2. Bumps it according to the label
14+
# 3. Runs scripts/sync-versions.sh to propagate the new version across all manifests
15+
# 4. Commits the bump to main and pushes tag v{new-version}
16+
# 5. The tag push then triggers release.yml → builds everything → draft GH Release
17+
#
18+
# If no release label is present, the workflow is a no-op. Merges without a label
19+
# just land the code on main as normal — releases are explicit opt-in.
20+
#
21+
# Alternative (manual): engineer can still run this flow manually:
22+
# scripts/sync-versions.sh 0.20.0
23+
# git tag v0.20.0 && git push origin v0.20.0
24+
# Both paths converge on release.yml.
25+
# =============================================================================
26+
27+
on:
28+
pull_request:
29+
types: [closed]
30+
branches: [main]
31+
32+
permissions:
33+
contents: write # needed to commit version bump + push tag
34+
pull-requests: write # needed for gh pr comment on the merged PR
35+
36+
jobs:
37+
auto-tag:
38+
if: github.event.pull_request.merged == true
39+
runs-on: ubuntu-latest
40+
steps:
41+
- name: Detect release label on merged PR
42+
id: label
43+
env:
44+
PR_LABELS: ${{ toJson(github.event.pull_request.labels) }}
45+
run: |
46+
set -euo pipefail
47+
# Extract just the label names
48+
NAMES=$(echo "$PR_LABELS" | jq -r '.[].name')
49+
echo "PR labels: $NAMES"
50+
51+
BUMP=""
52+
for name in $NAMES; do
53+
case "$name" in
54+
release:patch) BUMP="patch" ;;
55+
release:minor) BUMP="minor" ;;
56+
release:major) BUMP="major" ;;
57+
esac
58+
done
59+
60+
if [ -z "$BUMP" ]; then
61+
echo "No release:* label — nothing to do."
62+
echo "should-release=false" >> "$GITHUB_OUTPUT"
63+
else
64+
echo "Release label found: release:$BUMP"
65+
echo "should-release=true" >> "$GITHUB_OUTPUT"
66+
echo "bump=$BUMP" >> "$GITHUB_OUTPUT"
67+
fi
68+
69+
- name: Checkout main
70+
if: steps.label.outputs.should-release == 'true'
71+
uses: actions/checkout@v4
72+
with:
73+
ref: main
74+
fetch-depth: 0
75+
token: ${{ secrets.GITHUB_TOKEN }}
76+
77+
- name: Compute next version
78+
if: steps.label.outputs.should-release == 'true'
79+
id: version
80+
env:
81+
BUMP: ${{ steps.label.outputs.bump }}
82+
run: |
83+
set -euo pipefail
84+
CURRENT=$(grep -E '^PROJECT_VERSION=' sdk/runanywhere-commons/VERSIONS | cut -d= -f2 | xargs)
85+
# Strip any pre-release suffix for bumping
86+
BASE="${CURRENT%%-*}"
87+
IFS='.' read -r MAJOR MINOR PATCH <<< "$BASE"
88+
89+
case "$BUMP" in
90+
patch) PATCH=$((PATCH + 1)) ;;
91+
minor) MINOR=$((MINOR + 1)); PATCH=0 ;;
92+
major) MAJOR=$((MAJOR + 1)); MINOR=0; PATCH=0 ;;
93+
esac
94+
95+
NEW="${MAJOR}.${MINOR}.${PATCH}"
96+
echo "Current: $CURRENT"
97+
echo "Bump: $BUMP"
98+
echo "New: $NEW"
99+
echo "new-version=$NEW" >> "$GITHUB_OUTPUT"
100+
101+
- name: Sanity-check tag doesn't already exist
102+
if: steps.label.outputs.should-release == 'true'
103+
env:
104+
NEW_VERSION: ${{ steps.version.outputs.new-version }}
105+
run: |
106+
set -euo pipefail
107+
if git rev-parse "v${NEW_VERSION}" >/dev/null 2>&1; then
108+
echo "::error::Tag v${NEW_VERSION} already exists."
109+
exit 1
110+
fi
111+
112+
- name: Run sync-versions.sh
113+
if: steps.label.outputs.should-release == 'true'
114+
env:
115+
NEW_VERSION: ${{ steps.version.outputs.new-version }}
116+
run: |
117+
set -euo pipefail
118+
chmod +x scripts/sync-versions.sh
119+
./scripts/sync-versions.sh "${NEW_VERSION}"
120+
121+
- name: Configure git identity
122+
if: steps.label.outputs.should-release == 'true'
123+
run: |
124+
git config user.name "github-actions[bot]"
125+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
126+
127+
- name: Commit version bump + push tag
128+
if: steps.label.outputs.should-release == 'true'
129+
env:
130+
NEW_VERSION: ${{ steps.version.outputs.new-version }}
131+
BUMP: ${{ steps.label.outputs.bump }}
132+
PR_NUMBER: ${{ github.event.pull_request.number }}
133+
run: |
134+
set -euo pipefail
135+
git add -u
136+
if git diff --cached --quiet; then
137+
echo "No manifest changes from sync-versions.sh — unexpected; aborting"
138+
exit 1
139+
fi
140+
git commit -m "chore: release v${NEW_VERSION} (${BUMP} bump from PR #${PR_NUMBER})"
141+
git tag "v${NEW_VERSION}"
142+
git push origin main
143+
git push origin "v${NEW_VERSION}"
144+
echo "::notice::Pushed tag v${NEW_VERSION} — release.yml will now build and create a draft release"
145+
146+
- name: Comment on merged PR
147+
if: steps.label.outputs.should-release == 'true'
148+
env:
149+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
150+
PR_NUMBER: ${{ github.event.pull_request.number }}
151+
NEW_VERSION: ${{ steps.version.outputs.new-version }}
152+
run: |
153+
gh pr comment "$PR_NUMBER" --repo "${{ github.repository }}" --body "🚀 Auto-tagged **v${NEW_VERSION}** — release.yml is now building artifacts. The GitHub Release will be created as a draft; publish it after reviewing the assets."

0 commit comments

Comments
 (0)