Skip to content

Commit

Permalink
GH Actions: new workflow to automatically update certificate bundle
Browse files Browse the repository at this point in the history
This adds a new workflow which will automatically check the cURL website for an update to the certificate bundle once a day and if an updated bundle is found, it will automatically create a pull request against the `develop` branch to update the bundle in the Requests package.

The workflow will also update the certificate checksum file and verify the checksum of the downloaded certificate bundle.

Notes:
* A condition has been added to prevent the cron job from running on forks (to conserve resources).
* The workflow uses the recommended commands for automated downloads as per the https://curl.se/docs/caextract.html page.
    These recommended commands do a conditional download only when a file is changed and use an `etag*.txt` file to check whether the upstream file has changed.
    These `etag*.txt` files don't really need to be stored in the actual repo, so they have been added to the `.gitignore` file.
    In the workflow, these `etag*.txt` files are stored to and restored from a workflow cache to allow for the conditional download.
* While the workflow runs on a cron job and manual updating of the certificate file/checksum file should therefore never be needed, as an extra security measure, the workflow will also run whenever a PR is opened to update the certificate files or when a change to the certificate files is pushed to the `stable` or `develop` branch.
    Note: as PRs which are opened from within a workflow do not trigger new workflows to be run (= default behaviour for GitHub Actions), the PR potentially created by this workflow will not trigger a recursive run of this workflow.
* If a PR triggers this workflow and a certificate update would be needed, a (new) PR against the original PR will be opened with the certificate update.
* If the workflow is triggered via the cronjob or for a push against `stable`/`develop`, any PR which may be opened will be opened against `develop`.

Fixes 635
  • Loading branch information
jrfnl committed Feb 7, 2022
1 parent bf39e2e commit 1a0d0cd
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 1 deletion.
1 change: 0 additions & 1 deletion .github/release-checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ Template to use for release PRs from `develop` to `stable`

PR for tracking changes for the x.x.x release. Target release date: **DOW MONTH DAY YEAR**.
- [ ] Check if any dependencies need updating.
- [ ] Check if the `certificates/cacert.pem` file needs updating.
- [ ] Update the version constant in `src/Requests.php`.
- [ ] Add changelog for the release - PR #xxx
- [ ] Merge this PR.
Expand Down
99 changes: 99 additions & 0 deletions .github/workflows/update-cacert.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
name: Certificates

on:
# Run every day at 4:20.
schedule:
- cron: '20 4 * * *'
# Run on every push to `stable` and `develop`.
# Not using path selection here as it appears only the files in the last commit from the push are looked at.
push:
branches:
- 'stable'
- 'develop'
# And whenever this workflow is updated or a PR attempts to update the certificate files.
pull_request:
paths:
- '.github/workflows/update-cacert.yml'
- 'certificates/cacert.pem'
- 'certificates/cacert.pem.sha256'
# Also allow manually triggering the workflow.
workflow_dispatch:

# Cancels all previous workflow runs for the same branch that have not yet completed.
concurrency:
# The concurrency group contains the workflow name and the branch name.
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
certificate-check:
name: "Check for updated certificate bundle"
# Don't run the cron job on forks.
if: ${{ github.event_name != 'schedule' || github.repository == 'WordPress/Requests' }}

runs-on: ubuntu-latest
steps:
- name: Determine branches to use
id: branches
env:
HEAD_REF: ${{ github.head_ref }}
run: |
if [[ "${{ github.event_name }}" == 'schedule' ]]; then
echo "::set-output name=BASE::develop"
elif [[ "${{ github.event_name }}" == 'push' ]]; then
# Pull requests should always go to develop, even when triggered via stable.
echo "::set-output name=BASE::develop"
else # = PR or manual run.
echo "::set-output name=BASE::$HEAD_REF"
fi
- name: Checkout code
uses: actions/checkout@v2

- name: Restore etags cache for certificate files
uses: actions/cache@v2
with:
path: certificates/etag-*.txt
key: curl-etag-${{ hashFiles('certificates/cacert.pem') }}-${{ hashFiles('certificates/cacert.pem.sha256') }}
restore-keys: |
curl-etag-
- name: Get current certificate bundle if changed
working-directory: ./certificates
run: curl --etag-compare etag-cert.txt --etag-save etag-cert.txt --remote-name https://curl.se/ca/cacert.pem

- name: Get current SHA256 checksum file for the bundle if changed
working-directory: ./certificates
run: curl --etag-compare etag-sha.txt --etag-save etag-sha.txt --remote-name https://curl.se/ca/cacert.pem.sha256

- name: Verify the checksum of the downloaded bundle
working-directory: ./certificates
run: sha256sum --check cacert.pem.sha256

- name: "Debug info: Show git status"
run: git status -vv --untracked=all

# http://man7.org/linux/man-pages/man1/date.1.html
- name: "Get date"
id: get-date
run: echo "::set-output name=DATE::$(/bin/date -u "+%F")"

- name: Create pull request
uses: peter-evans/create-pull-request@v3
with:
base: ${{ steps.branches.outputs.BASE }}
branch: "feature/auto-update-cacert"
delete-branch: true
commit-message: ":lock_with_ink_pen: Update certificate bundle"
title: ":lock_with_ink_pen: Update certificate bundle"
body: |
Updated certificate bundle as of ${{ steps.get-date.outputs.DATE }}.
Source: https://curl.se/docs/caextract.html
This PR is auto-generated by [create-pull-request](https://github.com/peter-evans/create-pull-request) using the `.github/workflows/update-cacert.yml` workflow.
labels: |
Type: enhancement
reviewers: |
jrfnl
schlessera
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@ phpcs.xml
phpdoc.xml
build/ghpages/.phpdoc
build/ghpages/artifacts

# Ignore temporary files for certificate downloads.
certificates/etag-*.txt

0 comments on commit 1a0d0cd

Please sign in to comment.