Skip to content

Autoupdate uv lock file #2

Autoupdate uv lock file

Autoupdate uv lock file #2

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