Skip to content

feat(up): ✨ synchronize 'omni up' operations (#687) #247

feat(up): ✨ synchronize 'omni up' operations (#687)

feat(up): ✨ synchronize 'omni up' operations (#687) #247

name: Auto-pull-request for cargo dependencies
on:
# Run on push to main
push:
branches:
- main
paths:
- .github/workflows/auto-pr-cargo-dependencies.yaml
- Cargo.lock
# Run weekly
schedule:
- cron: '0 0 * * Sun'
# Needed so we can run it manually
workflow_dispatch:
permissions:
contents: read
defaults:
run:
shell: bash
env:
# So cargo doesn't complain about unstable features
RUSTC_BOOTSTRAP: 1
# Which branch to use to make the pull request
PR_BRANCH: auto/cargo_update
# Whether or not to enable auto-merge
PR_AUTO_MERGE: true
jobs:
check-pull-request:
name: Check if the pull request exists
runs-on: ubuntu-latest
if: github.repository_owner == 'XaF'
permissions:
contents: read
pull-requests: read
outputs:
pull_request_state: ${{ env.PR_STATE }}
should_run: ${{ github.event_name != 'push' || env.PR_STATE == 'OPEN' }}
steps:
- name: Checkout commit
uses: actions/checkout@v4
- name: Check if pull request already exists
env:
GITHUB_TOKEN: ${{ github.token }}
run: |
STATE=$(gh pr view "${{ env.PR_BRANCH }}" \
--repo "${{ github.repository }}" \
--json state --jq '.state' || \
echo "NOT FOUND")
echo "PR_STATE=${STATE}" | tee -a "$GITHUB_ENV"
run-cargo-update:
name: Update cargo dependencies
runs-on: ubuntu-latest
needs:
- check-pull-request
if: needs.check-pull-request.outputs.should_run == 'true'
outputs:
any_update: ${{ env.UPDATES }}
steps:
- name: Checkout commit
uses: actions/checkout@v4
- name: Get rust stable
uses: dtolnay/rust-toolchain@stable
- name: cargo update
run: |
cargo update --color=never 2>&1 \
| tee -a cargo_update.log
- name: Check if there is any update
run : |
[[ $(cat cargo_update.log | wc -l) -gt 1 ]] && \
UPDATES=true || \
UPDATES=false
echo "UPDATES=${UPDATES}" | tee -a "$GITHUB_ENV"
- name: upload Cargo.lock artifact for use in PR
if: ${{ env.UPDATES == 'true' }}
uses: actions/upload-artifact@v4
with:
name: Cargo-lock
path: Cargo.lock
retention-days: 1
- name: upload cargo-update log artifact for use in PR
if: ${{ env.UPDATES == 'true' }}
uses: actions/upload-artifact@v4
with:
name: cargo-updates
path: cargo_update.log
retention-days: 1
create-or-update-pr:
name: Create or update pull-request
runs-on: ubuntu-latest
needs:
- check-pull-request
- run-cargo-update
if: needs.check-pull-request.outputs.should_run == 'true' && needs.run-cargo-update.outputs.any_update == 'true'
env:
PR_TITLE: "chore(deps): 📦 cargo update"
steps:
- name: Create application token
uses: actions/create-github-app-token@v1
id: app-token
with:
app-id: ${{ secrets.OMNICLI_APP_ID }}
private-key: ${{ secrets.OMNICLI_PRIVATE_KEY }}
- name: Checkout commit
uses: actions/checkout@v4
with:
token: ${{ steps.app-token.outputs.token }}
- name: Download Cargo.lock from update job
uses: actions/download-artifact@v4
with:
name: Cargo-lock
- name: Download cargo-update log from update job
uses: actions/download-artifact@v4
with:
name: cargo-updates
- name: Craft commit message
run: |
echo "${{ env.PR_TITLE }}" | tee commit.txt
echo | tee -a commit.txt
cat cargo_update.log | tee -a commit.txt
- name: Craft pull-request body
run: |
echo 'Updating `Cargo.lock` with `cargo update`' | tee body.md
echo | tee -a body.md
echo "The following crate dependencies are to be updated:" | tee -a body.md
echo | tee -a body.md
awk 'NR > 1 && /Updating/ { \
sub(/^v/, "", $3); \
sub(/^v/, "", $5); \
printf "- [`%s`](https://crates.io/crates/%s) "\
"([`v%s`](https://docs.rs/%s/%s/) -> "\
"[`v%s`](https://docs.rs/%s/%s/))\n",
$2, $2, $3, $2, $3, $5, $2, $5
}' cargo_update.log | tee -a body.md
- name: git commit
run: |
git config user.name github-actions
git config user.email [email protected]
git switch --force-create "${{ env.PR_BRANCH }}"
git add ./Cargo.lock
git commit --no-verify --file=commit.txt
- name: git push
run: |
git push --no-verify --force --set-upstream origin "${{ env.PR_BRANCH }}"
- name: Create or update pull-request
env:
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
PR_STATE: ${{ needs.check-pull-request.outputs.pull_request_state }}
run: |
if [[ "$PR_STATE" != "OPEN" ]]; then
gh pr create \
--title "${{ env.PR_TITLE }}" \
--body-file body.md \
--repo "${{ github.repository }}" \
--label dependencies \
--label rust
else
gh pr edit "${{ env.PR_BRANCH }}" \
--title "${{ env.PR_TITLE }}" \
--body-file body.md \
--repo "${{ github.repository }}" \
--add-label dependencies \
--add-label rust
fi
- name: Enable auto-merge
if: ${{ env.PR_AUTO_MERGE == 'true' }}
env:
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
run: |
NUM=$(gh pr view "${{ env.PR_BRANCH }}" \
--repo "${{ github.repository }}" \
--json number --jq '.number' || \
echo "")
if [[ -z "$NUM" ]]; then
echo "Failed to get PR number"
exit 1
fi
gh pr merge --squash --auto --body "" "$NUM"
close-pr:
name: Close pull-request
runs-on: ubuntu-latest
needs:
- check-pull-request
- run-cargo-update
if: needs.check-pull-request.outputs.should_run == 'true' && needs.run-cargo-update.outputs.any_update == 'false' && needs.check-pull-request.outputs.pull_request_state == 'OPEN'
env:
PR_CLOSING_COMMENT: "Superseded. No more dependencies to be updated for now."
steps:
- name: Create application token
uses: actions/create-github-app-token@v1
id: app-token
env:
APP_ID: ${{ secrets.OMNICLI_APP_ID }}
PRIVATE_KEY: ${{ secrets.OMNICLI_PRIVATE_KEY }}
with:
app-id: ${{ env.APP_ID }}
private-key: ${{ env.PRIVATE_KEY }}
- name: Close pull-request
env:
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
run: |
gh pr close \
--title "${{ env.PR_TITLE }}" \
--comment "${{ env.PR_CLOSING_COMMENT }}" \
--delete-branch