Skip to content

Update packages

Update packages #69

name: Update packages
# Run periodically, but can also be triggered manually.
on:
schedule:
- cron: 0 14 * * 0 # Every Sunday at 2PM.
workflow_dispatch:
# Only allow one run at a time.
concurrency:
group: ${{ github.workflow }}
# Specify bash to enable `-eo pipefail`.
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsshell
defaults:
run:
shell: bash
jobs:
# Get the list of packages to update (has `passthru.updateScript`).
generate-matrix:
name: Get list of packages to update
runs-on: ubuntu-latest
# This workflow should only run on the main branch; running on other
# branches could be useful in some situations, but it might have unexpected
# consequences, so restricting it seems like the safest choice for now.
if: github.ref == 'refs/heads/main'
outputs:
packages: ${{ steps.matrix.outputs.packages }}
steps:
- name: Set up repository
uses: actions/checkout@v4
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@v10
- name: Get list of packages to update
id: matrix
run: ./automation.py get-packages-to-update | tee $GITHUB_STEP_SUMMARY
# Update the packages in parallel using a matrix strategy.
update:
name: Update ${{ matrix.package }}
runs-on: ubuntu-latest
needs: generate-matrix
permissions:
pull-requests: write # Write access is needed to create a pull request.
contents: write # Write access is needed to enable auto-merge.
# Skip this entire job if there are no packages to update.
if: needs.generate-matrix.outputs.packages != '[]'
strategy:
matrix:
package: ${{ fromJson(needs.generate-matrix.outputs.packages) }}
fail-fast: false # Keep going if some jobs fail.
steps:
- name: Set up repository
uses: actions/checkout@v4
with:
# Specifying the deploy key here sets it up to be used for pushing
# later; this is a workaround for GITHUB_TOKEN being unable to trigger
# workflows on push/pull request/etc.
# https://github.com/orgs/community/discussions/25702
ssh-key: ${{ secrets.DEPLOY_KEY }}
# Commits will be authored by the GitHub Actions bot user.
- name: Set up commit author
run: |
git config user.name github-actions[bot]
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@v10
# This will fail if the branch already exists; since pull requests created
# by this workflow should be auto-merged, an existing branch either means
# the checks for a previous pull request failed or are still running, so
# failing seems like the safest thing to do.
- name: Create branch for pull request
run: git checkout -b auto-update/${{ matrix.package }}
- name: Update ${{ matrix.package }}
run: |
echo \`\`\`\`text >> $GITHUB_STEP_SUMMARY
trap 'echo \`\`\`\` >> $GITHUB_STEP_SUMMARY' EXIT
./automation.py update-package ${{ matrix.package }} | tee -a $GITHUB_STEP_SUMMARY
env:
# TODO: This token is needed by update scripts that use the `gh` cli,
# but preferably there would be some way to avoid using a token with
# write permissions (just to be safe).
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create pull request
run: |
# There might not be a commit if everything is already up-to-date.
[[ $(git diff ${{ github.ref_name }}) ]] || exit 0
# Push the changes.
git push -u origin auto-update/${{ matrix.package }}
# Generate the pull request body.
PR_BODY=$(mktemp)
echo 'This pull request was created automatically by GitHub Actions :)' >> $PR_BODY
echo '<sub>**${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}**</sub>' >> $PR_BODY
# FIXME: updateScript might not always be a bash script!
echo '````bash' >> $PR_BODY
echo '$ nix build '"'.#${{ matrix.package }}.passthru.updateScript'"' && cat ./result' >> $PR_BODY
echo '---' >> $PR_BODY
nix build .#${{ matrix.package }}.passthru.updateScript && cat ./result >> $PR_BODY
echo '````' >> $PR_BODY
# Create the pull request and enable auto-merge.
gh pr merge --auto --rebase --delete-branch $(gh pr create \
--title "$(git show --no-patch --format=format:%s)" \
--body-file $PR_BODY \
--label "automated" --label "package update" \
)
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}