Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions .github/scripts/dependency-update-commit-and-push.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/usr/bin/env bash

# Commit generated dependency changes and update the reusable PR branch.

set -euo pipefail

: "${GITHUB_OUTPUT:?GITHUB_OUTPUT is required}"
: "${HAS_OPEN_PR:?HAS_OPEN_PR is required}"

if [[ "${HAS_OPEN_PR}" != "true" && "${HAS_OPEN_PR}" != "false" ]]; then
echo "HAS_OPEN_PR must be either true or false" >&2
exit 1
fi

changes_detected=false
if [[ -z "$(git status --porcelain)" ]]; then
echo "No changes detected"
else
echo "Changes detected"
git add --all
git commit -m "Update dependencies ($(date -u +%Y-%m-%d))"
changes_detected=true
fi

branch_pushed=false
if [[ "${HAS_OPEN_PR}" == "true" ]]; then
commits_to_push="$(git rev-list --count origin/update-dependencies..HEAD)"
if [[ "${commits_to_push}" -gt 0 ]]; then
git push origin HEAD:update-dependencies
branch_pushed=true
fi
elif [[ "${changes_detected}" == "true" ]]; then
# No open PR owns this branch, so replacing a stale remote branch cannot
# rewrite active review history.
git push --force-with-lease origin HEAD:update-dependencies
branch_pushed=true
fi

echo "branch_pushed=${branch_pushed}" >> "${GITHUB_OUTPUT}"
14 changes: 14 additions & 0 deletions .github/scripts/dependency-update-create-pr.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env bash

# Open a dependency-update PR after a new update branch has been pushed.

set -euo pipefail

: "${GITHUB_REPOSITORY:?GITHUB_REPOSITORY is required}"

gh pr create \
--repo "${GITHUB_REPOSITORY}" \
--title "Update dependencies" \
--body "Automated daily dependency updates. Subsequent runs append commits to this branch while the pull request remains open." \
--base main \
--head update-dependencies
36 changes: 36 additions & 0 deletions .github/scripts/dependency-update-prepare-branch.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/usr/bin/env bash

# Reuse the branch for an open dependency-update PR, or start a new branch
# from current main when no update PR exists.

set -euo pipefail

: "${GITHUB_REPOSITORY:?GITHUB_REPOSITORY is required}"
: "${GITHUB_OUTPUT:?GITHUB_OUTPUT is required}"

git config user.name "policyengine-auto"
git config user.email "policyengine-auto@users.noreply.github.com"

open_pr="$(
gh pr list \
--repo "${GITHUB_REPOSITORY}" \
--base main \
--head update-dependencies \
--state open \
--json number \
--jq '.[0].number // empty'
)"

if [[ -n "${open_pr}" ]]; then
echo "has_open_pr=true" >> "${GITHUB_OUTPUT}"
git fetch origin update-dependencies
git checkout -B update-dependencies origin/update-dependencies

# Preserve the open PR's commits while incorporating current main. Prefer
# main's version of conflicts because later steps regenerate clients and
# recreate dependency lock changes.
git merge --no-edit -X theirs origin/main
else
echo "has_open_pr=false" >> "${GITHUB_OUTPUT}"
git checkout -B update-dependencies origin/main
fi
65 changes: 25 additions & 40 deletions .github/workflows/update-dependencies.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@ name: Update dependencies

on:
schedule:
# Run every 15 minutes
- cron: '*/15 * * * *'
# Run daily at 3:00 PM US Eastern time.
- cron: '0 15 * * *'
timezone: 'America/New_York'
workflow_dispatch: # Allow manual triggering

concurrency:
group: update-dependencies
cancel-in-progress: false

jobs:
update-dependencies:
name: File update PR
Expand All @@ -25,9 +30,9 @@ jobs:

- name: Checkout repository
uses: actions/checkout@v6
# Checkout main branch
with:
ref: main
fetch-depth: 0
token: ${{ steps.app-token.outputs.token }}

- name: Install uv
Expand All @@ -37,47 +42,27 @@ jobs:
uses: actions/setup-python@v6
with:
python-version: "3.13"

- name: Prepare update branch
id: branch
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
run: .github/scripts/dependency-update-prepare-branch.sh

- name: Generate API clients
run: |
# Generate clients with correct naming before updating dependencies
./scripts/generate-clients.sh
run: ./scripts/generate-clients.sh

- name: Update dependencies
id: update
run: |
# Run the update command
make update

# Check if there are changes
if [[ -z $(git status --porcelain) ]]; then
echo "No changes detected"
echo "changes_detected=false" >> $GITHUB_OUTPUT
else
echo "Changes detected"
echo "changes_detected=true" >> $GITHUB_OUTPUT
fi

- name: Create pull request
if: steps.update.outputs.changes_detected == 'true'
run: |
git config --global user.name "policyengine-auto"
git config --global user.email "policyengine-auto@users.noreply.github.com"

git checkout -b update-dependencies
git add .
git commit -m "Update dependencies"
git push origin update-dependencies --force

# Try to create PR, ignore if it already exists
gh pr create \
--title "Update dependencies" \
--body "Automated dependency updates
run: make update

This PR was automatically created by the dependency update workflow.
- name: Commit and push update
id: push
env:
HAS_OPEN_PR: ${{ steps.branch.outputs.has_open_pr }}
run: .github/scripts/dependency-update-commit-and-push.sh

Last updated: $(date)" \
--base main \
--head update-dependencies || echo "PR may already exist, continuing..."
- name: Create pull request
if: steps.branch.outputs.has_open_pr == 'false' && steps.push.outputs.branch_pushed == 'true'
env:
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
GH_TOKEN: ${{ steps.app-token.outputs.token }}
run: .github/scripts/dependency-update-create-pr.sh
Loading