-
Notifications
You must be signed in to change notification settings - Fork 213
141 lines (119 loc) · 5.65 KB
/
Copy pathdep_update_guest_locks.yml
File metadata and controls
141 lines (119 loc) · 5.65 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
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
# This reusable workflow updates the guest workspace Cargo.lock when
# Dependabot updates dependencies. Without this, Dependabot PRs only update the
# root Cargo.lock, leaving the guest workspace Cargo.lock stale.
#
# See: https://docs.github.com/en/code-security/tutorials/secure-your-dependencies/automating-dependabot-with-github-actions
name: Update Guest Cargo.lock for Dependabot PRs
on:
workflow_call:
env:
CARGO_TERM_COLOR: always
permissions:
contents: read
defaults:
run:
shell: bash
jobs:
update-guest-locks:
runs-on: [self-hosted, Linux, X64, "1ES.Pool=hld-kvm-amd", "JobId=update-guest-locks-${{ github.run_id }}-${{ github.run_number }}-${{ github.run_attempt }}"]
timeout-minutes: 15
steps:
# Get GitHub App token for pushing commits back to the PR
- name: Get GitHub App token
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
id: get-app-token
with:
app-id: ${{ secrets.DEPENDABOT_APP_ID }}
private-key: ${{ secrets.DEPENDABOT_APP_KEY }}
permission-contents: write
- name: Checkout PR branch
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
token: ${{ steps.get-app-token.outputs.token }}
ref: ${{ github.head_ref }}
fetch-depth: 0
persist-credentials: false
- name: Setup Rust toolchain
uses: hyperlight-dev/ci-setup-workflow@f6bd9cc86d0737976d2128c8b8ced8edc017cbb4 # v1.9.0
with:
rust-toolchain: "1.94"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Fix cargo home permissions
run: |
sudo chown -R $(id -u):$(id -g) /opt/cargo || true
- name: Update guest Cargo.lock
working-directory: src/tests/rust_guests
run: cargo fetch
# Commits created via the Git Data API are automatically signed/verified
# by GitHub when authenticated as a GitHub App and no custom author or
# committer info is provided.
#
# References:
# - Signature verification for bots:
# https://docs.github.com/en/authentication/managing-commit-signature-verification/about-commit-signature-verification#signature-verification-for-bots
# - How to Use Commit Signing with GitHub Apps:
# https://github.com/orgs/community/discussions/50055
# - Git Data API (Create a commit):
# https://docs.github.com/en/rest/git/commits#create-a-commit
- name: Commit and push changes via API
env:
GH_TOKEN: ${{ steps.get-app-token.outputs.token }}
APP_SLUG: ${{ steps.get-app-token.outputs.app-slug }}
PR_TITLE: ${{ github.event.pull_request.title }}
BRANCH: ${{ github.head_ref }}
REPO: ${{ github.repository }}
run: |
set -euo pipefail
# Check if there are any changes to the guest Cargo.lock file
if git diff --quiet -- src/tests/rust_guests/Cargo.lock; then
echo "No changes to guest Cargo.lock file"
exit 0
fi
echo "Guest Cargo.lock file has changed, committing via API..."
# Get app identity for DCO sign-off trailer
# Use the app-slug output from create-github-app-token (the /app API
# endpoint requires JWT auth, not an installation token).
app_slug="${APP_SLUG}"
app_user_id=$(gh api "/users/${app_slug}[bot]" --jq .id)
# Get current branch HEAD and its tree
HEAD_SHA=$(gh api "/repos/${REPO}/git/ref/heads/${BRANCH}" --jq .object.sha)
BASE_TREE=$(gh api "/repos/${REPO}/git/commits/${HEAD_SHA}" --jq .tree.sha)
# Build tree entries with file content for each changed Cargo.lock.
# The tree API accepts "content" directly and creates blobs for us,
# avoiding the need for separate blob creation API calls.
TREE_JSON="[]"
for file in $(git diff --name-only -- src/tests/rust_guests/Cargo.lock); do
TREE_JSON=$(jq \
--arg path "$file" \
--arg content "$(cat "$file")" \
'. + [{"path": $path, "mode": "100644", "type": "blob", "content": $content}]' \
<<< "$TREE_JSON")
done
# Create a new tree with the updated files
NEW_TREE=$(jq -n \
--arg base "$BASE_TREE" \
--argjson tree "$TREE_JSON" \
'{"base_tree": $base, "tree": $tree}' | \
gh api "/repos/${REPO}/git/trees" --input - --jq .sha)
# Build commit message with DCO sign-off
SIGNOFF="${app_slug}[bot] <${app_user_id}+${app_slug}[bot]@users.noreply.github.com>"
COMMIT_MSG=$(printf '%s\n\n%s\n%s\n\n%s' \
"chore: update guest Cargo.lock file" \
"Automatically updated by dependabot-update-guest-locks workflow." \
"Triggered by: ${PR_TITLE}" \
"Signed-off-by: ${SIGNOFF}")
# Create commit via API — GitHub signs it automatically since we
# authenticate as the App and omit custom author/committer info.
NEW_COMMIT=$(jq -n \
--arg msg "$COMMIT_MSG" \
--arg tree "$NEW_TREE" \
--arg parent "$HEAD_SHA" \
'{"message": $msg, "tree": $tree, "parents": [$parent]}' | \
gh api "/repos/${REPO}/git/commits" --input - --jq .sha)
# Update branch ref to point to the new commit
gh api "/repos/${REPO}/git/refs/heads/${BRANCH}" \
-X PATCH \
-f sha="${NEW_COMMIT}"
echo "Successfully committed and pushed changes"