-
Notifications
You must be signed in to change notification settings - Fork 2
143 lines (138 loc) · 6.2 KB
/
uv_lock_autoupdate.yml
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
name: Autoupdate uv lock file
on:
schedule:
# Every Sunday at 00:00.
- cron: "0 0 * * 0"
jobs:
uv_lock_autoupdate:
env:
lockfile_path: uv.lock
requirements_doc_path: requirements-doc.txt
update_message_path: /tmp/message.txt
update_branch: chore/uv-lock-autoupdate
runs-on: ubuntu-latest
steps:
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.WRITE_CONTENTS_PR_APP }}
private-key: ${{ secrets.WRITE_CONTENTS_PR_KEY }}
- uses: actions/checkout@v4
with:
ref: main
- name: Create or checkout update branch
id: create_branch
env:
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
run: |
export pr_number=$( gh pr view ${{ env.update_branch }} --json number --jq '.number' )
export pr_state=$( gh pr view ${{ env.update_branch }} --json state --jq '.state' )
echo "pr_number=$pr_number" >> "$GITHUB_OUTPUT"
echo "pr_state=$pr_state" >> "$GITHUB_OUTPUT"
if git fetch origin ${{ env.update_branch }}; then
# If branch wasn't deleted after merge, do so here
if [ "$pr_state" = "MERGED" ]; then
git push -d origin ${{ env.update_branch }}
git checkout -b ${{ env.update_branch }}
git push origin ${{ env.update_branch }}
fi
git checkout ${{ env.update_branch }}
else
git checkout -b ${{ env.update_branch }}
git push origin ${{ env.update_branch }}
fi
# uv setup and lockfile upgrading steps
- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: 3.12
cache: pip
- name: Upgrade Pip
run: python -m pip install --upgrade pip
- name: Install uv
run: pip install uv
- name: Store hash of baseline files for comparison
id: old_hash
run: |
echo "lockfile=$( sha256sum $lockfile_path )" >> $GITHUB_OUTPUT
echo "requirements_doc=$( sha256sum $requirements_doc_path )" >> $GITHUB_OUTPUT
- name: Overwrite config on branch with version from main
run: |
git checkout main ${{ env.lockfile_path }}
git checkout main ${{ env.requirements_doc_path }}
- name: Store hash of main files for comparison
id: main_hash
run: |
echo "lockfile=$( sha256sum $lockfile_path )" >> $GITHUB_OUTPUT
echo "requirements_doc=$( sha256sum $requirements_doc_path )" >> $GITHUB_OUTPUT
- name: Run `uv lock --upgrade` on main lockfile
id: autoupdate
run: |
uv lock --upgrade > ${{ env.update_message_path }}
cat ${{ env.update_message_path }}
sed -i "/updated/!d" ${{ env.update_message_path }}
- name: Update requirements-docs.txt
run: >
uv export
--frozen
--format requirements-txt
--no-hashes
--no-dev
--no-emit-project
--extra doc
--output-file requirements-doc.txt
- name: Store hash of new files for comparison
id: new_hash
run: |
echo "lockfile=$( sha256sum $lockfile_path )" >> $GITHUB_OUTPUT
echo "requirements_doc=$( sha256sum $requirements_doc_path )" >> $GITHUB_OUTPUT
# Commit authoring and pull-request creation/updating
- name: Commit (with signature) lockfile
id: commit_lockfile
if: steps.old_hash.outputs.lockfile != steps.new_hash.outputs.lockfile
env:
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
run: |
export message="chore(deps): autoupdate uv.lock"
export sha=$( git rev-parse ${{ env.update_branch }}:${{ env.lockfile_path }} )
base64 -i ${{ env.lockfile_path }} > $RUNNER_TEMP/base64_lockfile
gh api --method PUT /repos/:owner/:repo/contents/${{ env.lockfile_path }} \
--field message="$message" \
--field content="@$RUNNER_TEMP/base64_lockfile" \
--field branch=${{ env.update_branch }} \
--field sha="$sha"
- name: Commit (with signature) new requirements-doc
id: commit_requirements_doc
if: steps.old_hash.outputs.requirements_doc != steps.new_hash.outputs.requirements_doc
env:
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
run: |
export message="chore(deps): autoupdate requirements-doc"
export sha=$( git rev-parse ${{ env.update_branch }}:${{ env.requirements_doc_path }} )
base64 -i ${{ env.requirements_doc_path }} > $RUNNER_TEMP/base64_requirements_doc
gh api --method PUT /repos/:owner/:repo/contents/${{ env.requirements_doc_path }} \
--field message="$message" \
--field content="@$RUNNER_TEMP/base64_requirements_doc" \
--field branch=${{ env.update_branch }} \
--field sha="$sha"
- name: Create or update lockfile-autoupdate pull-request
# note that we don't check whether requirements-doc was updated, as
# requirements-doc should only change if the lockfile also changes
if: steps.commit_lockfile.conclusion == 'success' || ( steps.main_lockfile.outputs.hash != steps.new_lockfile.outputs.hash )
env:
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
run: |
export title="chore(deps): autoupdate uv.lock"
export body=$( cat ${{ env.update_message_path }} )
export pr_number=${{ steps.create_branch.outputs.pr_number }}
export pr_state=${{ steps.create_branch.outputs.pr_state }}
# If the PR is closed, can it be reopened, or is the PR already open?
if ( [ "$pr_state" = "CLOSED" ] && gh pr reopen $pr_number ) || [ "$pr_state" = "OPEN" ]; then
gh api --method PATCH /repos/:owner/:repo/pulls/$pr_number \
--field title="$title" \
--field body="$body"
else
# If a PR doesn't already exist, and no previous PR can be reopened, create a new PR.
gh pr create -t "$title" -b "$body" -l dependencies -B main -H ${{ env.update_branch }}
fi