Skip to content

Commit a1d1f2b

Browse files
committed
Setup minimal CI
1 parent 2fe6ca3 commit a1d1f2b

2 files changed

Lines changed: 249 additions & 0 deletions

File tree

.github/workflows/docker.yaml

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
name: Build and push Docker image
2+
3+
on:
4+
push:
5+
branches: ["main", "release", "setup-CI"] # TODO: remove setup-CI after testing
6+
7+
jobs:
8+
docker:
9+
name: Build and push Docker image
10+
runs-on: ubuntu-latest
11+
env:
12+
AWS_REGION: us-east-1
13+
ECR_REGISTRY: 336594912921.dkr.ecr.us-east-1.amazonaws.com
14+
APP_NAME: rpc-proxy
15+
steps:
16+
- name: Checkout code
17+
uses: actions/checkout@v4
18+
with:
19+
fetch-depth: 0 # needed for git describe to find tags
20+
21+
- name: Configure AWS credentials
22+
uses: aws-actions/configure-aws-credentials@v4
23+
with:
24+
aws-access-key-id: ${{ secrets.ECR_AWS_ACCESS_KEY_ID }}
25+
aws-secret-access-key: ${{ secrets.ECR_AWS_SECRET_ACCESS_KEY }}
26+
aws-region: ${{ env.AWS_REGION }}
27+
28+
- name: Login to Amazon ECR
29+
id: login-ecr
30+
uses: aws-actions/amazon-ecr-login@v2
31+
32+
- name: Set image metadata
33+
id: meta
34+
run: |
35+
SHORT_SHA=${GITHUB_SHA:0:7}
36+
# Derive version from the nearest upstream tag (e.g. 0.0.62-2-g2fe6ca3)
37+
BASE_VERSION=$(git describe --tags --always)
38+
VERSION="custom-${BASE_VERSION}"
39+
if [[ "$GITHUB_REF_NAME" == "main" ]]; then
40+
TAGS="dev latest"
41+
DEPLOYMENT_ENV="dev"
42+
elif [[ "$GITHUB_REF_NAME" == "release" ]]; then
43+
TAGS="prod"
44+
DEPLOYMENT_ENV="prod"
45+
else
46+
# Use branch name as tag, sanitized for Docker tag format
47+
TAGS=$(echo "$GITHUB_REF_NAME" | sed 's/[^a-zA-Z0-9._-]/-/g')
48+
DEPLOYMENT_ENV="dev" # TODO: remove hack, only for testing promotion from setup-CI branch
49+
fi
50+
# Build full Docker tags (registry/app:tag) for each tag + short SHA
51+
DOCKER_TAGS=""
52+
for T in $TAGS $SHORT_SHA; do
53+
DOCKER_TAGS="${DOCKER_TAGS}${ECR_REGISTRY}/${APP_NAME}:${T}"$'\n'
54+
done
55+
echo "short_sha=$SHORT_SHA" >> "$GITHUB_OUTPUT"
56+
echo "tags=$TAGS" >> "$GITHUB_OUTPUT"
57+
echo "deployment_env=$DEPLOYMENT_ENV" >> "$GITHUB_OUTPUT"
58+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
59+
echo "docker_tags<<EOF" >> "$GITHUB_OUTPUT"
60+
echo "$DOCKER_TAGS" >> "$GITHUB_OUTPUT"
61+
echo "EOF" >> "$GITHUB_OUTPUT"
62+
echo "Image version: $VERSION (tags: $TAGS)"
63+
64+
- name: Set up Docker Buildx
65+
uses: docker/setup-buildx-action@v3
66+
67+
- name: Build and push image
68+
uses: docker/build-push-action@v6
69+
with:
70+
context: .
71+
push: true
72+
tags: ${{ steps.meta.outputs.docker_tags }}
73+
build-args: |
74+
VERSION=${{ steps.meta.outputs.version }}
75+
COMMIT_SHA=${{ steps.meta.outputs.short_sha }}
76+
cache-from: type=registry,ref=${{ env.ECR_REGISTRY }}/${{ env.APP_NAME }}:cache
77+
cache-to: type=registry,ref=${{ env.ECR_REGISTRY }}/${{ env.APP_NAME }}:cache,mode=max
78+
79+
- name: Promote image via infra workflow
80+
if: ${{ steps.meta.outputs.deployment_env != '' }}
81+
env:
82+
GH_TOKEN: ${{ secrets.INFRA_WORKFLOW_PAT }}
83+
GH_WORKFLOW_OWNER: rhinestonewtf
84+
GH_WORKFLOW_REPO: infra
85+
WORKFLOW_FILE: aws-promote-app-version.yaml
86+
DEPLOYMENT_ENV: ${{ steps.meta.outputs.deployment_env }}
87+
SHORT_SHA: ${{ steps.meta.outputs.short_sha }}
88+
run: |
89+
set -euo pipefail
90+
91+
if [[ -z "${GH_TOKEN:-}" ]]; then
92+
echo "INFRA_WORKFLOW_PAT secret is not configured" >&2
93+
exit 1
94+
fi
95+
96+
TARGET_REF="main"
97+
WORKFLOW_PATH=".github/workflows/$WORKFLOW_FILE"
98+
99+
WORKFLOW_METADATA=$(gh api repos/$GH_WORKFLOW_OWNER/$GH_WORKFLOW_REPO/actions/workflows/$WORKFLOW_FILE)
100+
WORKFLOW_ID=$(echo "$WORKFLOW_METADATA" | jq -r '.id // empty')
101+
102+
if [[ -z "$WORKFLOW_ID" ]]; then
103+
echo "Unable to resolve workflow id for $WORKFLOW_PATH" >&2
104+
exit 1
105+
fi
106+
107+
echo "Dispatching $WORKFLOW_FILE (id: $WORKFLOW_ID) in $GH_WORKFLOW_OWNER/$GH_WORKFLOW_REPO for env $DEPLOYMENT_ENV (version $SHORT_SHA)"
108+
109+
API_ROOT="https://api.github.com"
110+
DISPATCH_URL="$API_ROOT/repos/$GH_WORKFLOW_OWNER/$GH_WORKFLOW_REPO/actions/workflows/$WORKFLOW_FILE/dispatches"
111+
AUTH_HEADER=(
112+
-H "Authorization: Bearer $GH_TOKEN"
113+
-H "Accept: application/vnd.github+json"
114+
-H "Content-Type: application/json"
115+
)
116+
117+
DISPATCH_BODY=$(jq -n \
118+
--arg ref "$TARGET_REF" \
119+
--arg env "$DEPLOYMENT_ENV" \
120+
--arg app "$APP_NAME" \
121+
--arg sha "$SHORT_SHA" \
122+
'{ref: $ref, inputs: {env: $env, app_name: $app, version_sha: $sha}}')
123+
124+
DISPATCH_STATUS=$(curl -sS -o /tmp/dispatch.json -w "%{http_code}" "${AUTH_HEADER[@]}" \
125+
-X POST "$DISPATCH_URL" \
126+
-d "$DISPATCH_BODY")
127+
128+
if [[ "$DISPATCH_STATUS" -ge 300 ]]; then
129+
echo "Failed to dispatch remote workflow (status $DISPATCH_STATUS)" >&2
130+
cat /tmp/dispatch.json >&2 || true
131+
exit 1
132+
fi
133+
134+
echo "Awaiting workflow run to be created..."
135+
sleep 10
136+
137+
RUN_ID=$(gh api https://api.github.com/repos/$GH_WORKFLOW_OWNER/$GH_WORKFLOW_REPO/actions/runs --jq '[.workflow_runs[] | select(.event == "workflow_dispatch")][0].id' | sed 's/\x1b\[[0-9;]*m//g')
138+
echo "Run ID: $RUN_ID"
139+
140+
if [[ -z "$RUN_ID" ]]; then
141+
echo "Failed to find the dispatched workflow run" >&2
142+
exit 1
143+
fi
144+
145+
gh run watch "$RUN_ID" --repo $GH_WORKFLOW_OWNER/$GH_WORKFLOW_REPO --exit-status --compact --interval 15
146+
147+
- name: Notify Slack of deployment
148+
if: ${{ success() && steps.meta.outputs.deployment_env != '' }}
149+
env:
150+
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
151+
run: |
152+
if [[ -z "${SLACK_WEBHOOK:-}" ]]; then
153+
echo "SLACK_WEBHOOK secret is not configured" >&2
154+
exit 1
155+
fi
156+
157+
MESSAGE=$(jq -n \
158+
--arg text ":rocket: App *${{ env.APP_NAME }}* is live on *${{ steps.meta.outputs.deployment_env }}* version: *${{ steps.meta.outputs.short_sha }}*" \
159+
'{text: $text}')
160+
161+
curl -sSf -X POST -H 'Content-type: application/json' --data "$MESSAGE" "$SLACK_WEBHOOK"

sync-with-upstream.sh

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
UPSTREAM_REMOTE="upstream"
5+
UPSTREAM_URL="https://github.com/erpc/erpc"
6+
ORIGIN_REMOTE="origin"
7+
BRANCH="main"
8+
9+
usage() {
10+
echo "Usage: $0 <tag>"
11+
echo ""
12+
echo "Syncs the fork with an upstream release tag."
13+
echo " 1. Ensures upstream remote exists"
14+
echo " 2. Fetches the tag from upstream"
15+
echo " 3. Rebases our commits on top of it"
16+
echo " 4. Pushes main branch and the tag to origin"
17+
echo ""
18+
echo "Example: $0 0.0.63"
19+
exit 1
20+
}
21+
22+
if [[ $# -ne 1 ]]; then
23+
usage
24+
fi
25+
26+
TAG="$1"
27+
28+
# Ensure we're on the right branch
29+
CURRENT_BRANCH=$(git branch --show-current)
30+
if [[ "$CURRENT_BRANCH" != "$BRANCH" ]]; then
31+
echo "Error: must be on '$BRANCH' branch (currently on '$CURRENT_BRANCH')"
32+
exit 1
33+
fi
34+
35+
# Ensure working tree is clean (tracked changes + untracked files)
36+
if ! git diff --quiet || ! git diff --cached --quiet || [[ -n "$(git ls-files --others --exclude-standard)" ]]; then
37+
echo "Error: working tree is not clean. Commit or stash changes first."
38+
git status --short
39+
exit 1
40+
fi
41+
42+
# Ensure upstream remote exists
43+
if ! git remote get-url "$UPSTREAM_REMOTE" &>/dev/null; then
44+
echo "Adding upstream remote: $UPSTREAM_URL"
45+
git remote add "$UPSTREAM_REMOTE" "$UPSTREAM_URL"
46+
fi
47+
48+
# Fetch the specific tag from upstream
49+
echo "Fetching tag '$TAG' from upstream..."
50+
git fetch "$UPSTREAM_REMOTE" "refs/tags/$TAG:refs/tags/$TAG"
51+
52+
# Verify the tag exists
53+
if ! git rev-parse "$TAG" &>/dev/null; then
54+
echo "Error: tag '$TAG' not found after fetch"
55+
exit 1
56+
fi
57+
58+
# Show what will be rebased
59+
CUSTOM_COMMITS=$(git log --oneline "$TAG"..HEAD 2>/dev/null || true)
60+
if [[ -z "$CUSTOM_COMMITS" ]]; then
61+
echo "No custom commits to rebase — already up to date with '$TAG'"
62+
exit 0
63+
fi
64+
65+
echo ""
66+
echo "Custom commits to rebase on top of '$TAG':"
67+
echo "$CUSTOM_COMMITS"
68+
echo ""
69+
read -rp "Proceed with rebase? [y/N] " confirm
70+
if [[ "$confirm" != [yY] ]]; then
71+
echo "Aborted."
72+
exit 1
73+
fi
74+
75+
# Rebase our commits on top of the tag
76+
echo "Rebasing on top of '$TAG'..."
77+
git rebase "$TAG"
78+
79+
# Push updated branch and the tag to origin
80+
echo "Pushing '$BRANCH' branch to origin..."
81+
git push "$ORIGIN_REMOTE" "$BRANCH" --force-with-lease
82+
83+
echo "Pushing tag '$TAG' to origin..."
84+
git push "$ORIGIN_REMOTE" "refs/tags/$TAG"
85+
86+
echo ""
87+
echo "Done! Branch '$BRANCH' rebased on '$TAG' and pushed to origin."
88+
echo "Version will be: custom-$(git describe --tags --always)"

0 commit comments

Comments
 (0)