Sync dry-run from dist-$STACK-develop/ to dist-$STACK-stable/ #48
Workflow file for this run
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Platform packages sync from -develop/ to -stable/ | |
run-name: Sync${{ inputs.dry-run == true && ' dry-run' || '' }} from dist-$STACK-develop/ to dist-$STACK-stable/ | |
env: | |
stacks_list_for_shell_expansion: "{heroku-20,heroku-22}" | |
on: | |
workflow_dispatch: | |
inputs: | |
stack-heroku-20: | |
description: 'Sync heroku-20 packages' | |
type: boolean | |
default: true | |
required: false | |
stack-heroku-22: | |
description: 'Sync heroku-22 packages' | |
type: boolean | |
default: true | |
required: false | |
dry-run: | |
description: 'Only list package changes, without syncing' | |
type: boolean | |
default: false | |
required: false | |
permissions: | |
contents: read | |
jobs: | |
stack-list: | |
runs-on: ubuntu-22.04 | |
outputs: | |
stacks: ${{ steps.list-stacks.outputs.matrix }} | |
steps: | |
- id: list-stacks | |
name: Generate list of stacks to sync based on input checkboxes | |
run: | | |
echo '## Stacks to sync' >> "$GITHUB_STEP_SUMMARY" | |
set -o pipefail | |
stacks=(${{ inputs.stack-heroku-20 == true && 'heroku-20' || ''}} ${{ inputs.stack-heroku-22 == true && 'heroku-22' || ''}}) | |
printf "%s\n" "${stacks[@]}" | xargs -n1 echo - >> "$GITHUB_STEP_SUMMARY" | |
echo -n "matrix=" >> "$GITHUB_OUTPUT" | |
printf "%s\n" "${stacks[@]}" | jq -jcRn '[inputs|select(length>0)]' >> "$GITHUB_OUTPUT" | |
docker-build: | |
needs: [stack-list] | |
if: ${{ false && needs.stack-list.outputs.stacks != '[]' && needs.stack-list.outputs.stacks != '' }} | |
runs-on: ubuntu-22.04 | |
strategy: | |
matrix: | |
stack: ${{ fromJSON(needs.stack-list.outputs.stacks) }} | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Restore cached Docker image | |
id: restore-docker | |
uses: actions/cache/restore@v3 | |
with: | |
key: docker-cache-heroku-php-build-${{matrix.stack}}.${{github.sha}} | |
path: /tmp/docker-cache.tar.gz | |
- name: Load cached Docker image | |
if: steps.restore-docker.outputs.cache-hit == 'true' | |
run: docker load -i /tmp/docker-cache.tar.gz | |
- name: Build Docker image | |
if: steps.restore-docker.outputs.cache-hit != 'true' | |
run: docker build --tag heroku-php-build-${{matrix.stack}}:${{github.sha}} --file support/build/_docker/${{matrix.stack}}.Dockerfile . | |
- name: Save built Docker image | |
if: steps.restore-docker.outputs.cache-hit != 'true' | |
run: docker save heroku-php-build-${{matrix.stack}}:${{github.sha}} | gzip -1 > /tmp/docker-cache.tar.gz | |
- name: Cache built Docker image | |
if: steps.restore-docker.outputs.cache-hit != 'true' | |
uses: actions/cache/save@v3 | |
with: | |
key: ${{ steps.restore-docker.outputs.cache-primary-key }} | |
path: /tmp/docker-cache.tar.gz | |
sync: | |
needs: [stack-list, docker-build] | |
if: ${{ false && needs.stack-list.outputs.stacks != '[]' && needs.stack-list.outputs.stacks != '' }} | |
runs-on: ubuntu-22.04 | |
strategy: | |
matrix: | |
stack: ${{ fromJSON(needs.stack-list.outputs.stacks) }} | |
env: | |
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Restore cached Docker build | |
uses: actions/cache/restore@v3 | |
with: | |
key: docker-cache-heroku-php-build-${{matrix.stack}}.${{github.sha}} | |
path: /tmp/docker-cache.tar.gz | |
- name: Load cached Docker image | |
run: docker load -i /tmp/docker-cache.tar.gz | |
- name: Dry-run sync.sh to show package changes available for syncing to production bucket | |
if: ${{ inputs.dry-run == true }} | |
run: | | |
set -o pipefail | |
(yes n 2>/dev/null || true) | docker run --rm -i --env-file=support/build/_docker/env.default heroku-php-build-${{matrix.stack}}:${{github.sha}} sync.sh lang-php dist-${{matrix.stack}}-stable/ 2>&1 | tee sync.out | |
- name: Sync changed packages to production bucket | |
if: ${{ inputs.dry-run == false }} | |
run: | | |
set -o pipefail | |
(yes 2>/dev/null || true) | docker run --rm -i --env-file=support/build/_docker/env.default heroku-php-build-${{matrix.stack}}:${{github.sha}} sync.sh lang-php dist-${{matrix.stack}}-stable/ 2>&1 | tee sync.out | |
- name: Output job summary | |
run: | | |
echo '## Package changes ${{ inputs.dry-run == true && 'available for syncing' || 'synced' }} to ${{matrix.stack}} production bucket' >> "$GITHUB_STEP_SUMMARY" | |
echo "${{ inputs.dry-run == true && '**This is output from a dry-run**, no changes have been synced to production:' || '-n' }}" >> "$GITHUB_STEP_SUMMARY" | |
echo '```' >> "$GITHUB_STEP_SUMMARY" | |
sed -n '/The following packages will/,$p' sync.out >> "$GITHUB_STEP_SUMMARY" | |
echo '```' >> "$GITHUB_STEP_SUMMARY" | |
devcenter-generate: | |
needs: sync | |
if: always() | |
runs-on: ubuntu-22.04 | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Install dos2unix | |
run: | | |
sudo apt-get update | |
sudo apt-get install dos2unix | |
- name: Install PHP and Composer | |
uses: shivammathur/setup-php@v2 | |
with: | |
php-version: "8.2" | |
tools: "composer:2.6" | |
- name: Install Dev Center generator dependencies | |
run: | | |
composer install -d support/devcenter/ | |
- name: Generate Dev Center article tables | |
run: | | |
set -o pipefail | |
urls=( https://lang-php.s3.amazonaws.com/dist-${{ env.stacks_list_for_shell_expansion }}-${{ inputs.dry-run == true && 'develop' || 'stable' }}/packages.json ) | |
# generate.php can generate individual sections, but doing it in one go a) is faster and b) means this code does not need to know what those sections are | |
# Instead we split the generated contents into individual files, with the known delimiter as the split pattern. | |
support/devcenter/generate.php "${urls[@]}" | csplit -z -f 'section-' -b '%02d.md' - '/^<!-- BEGIN [A-Z_][A-Z0-9_-]\+ -->$/' '{*}' | |
# sanity check number of generated splits (e.g. in case the split ever changes) | |
shopt -s nullglob | |
splits=( section-*.md ) | |
if (( ${#splits[@]} < 2 )); then | |
echo 'Error: expected more than one split from input' | |
exit 1 | |
fi | |
- name: Download current Dev Center article markdown | |
run: | | |
curl -H "Accept: application/json" https://devcenter.heroku.com/api/v1/articles/2021 | jq -j '.content' > php-support.md | |
# Because the articles are edited in a web interface, they likely use CRLF line endings. | |
# We will be patching using the LF line ending section files generated in an earlier step. | |
# For this reason, we may have to convert to LF, so we check if the file would be converted by dos2unix using the --info option. | |
# The "c" info flag prints only file names that would trigger conversion; we first remember this output for the next step via tee -a. | |
# The "0" flag triggers zero-byte output for happy consumption by xargs | |
# Then, we finally run the conversion (if needed) by passing the file name to dos2unix again via xargs. | |
dos2unix --info=c0 php-support.md | tee have_crlf.txt | xargs -r0 dos2unix | |
- name: Replace Dev Center article tables with generated tables | |
run: | | |
# init ed script (https://www.gnu.org/software/diffutils/manual/html_node/Detailed-ed.html) for patching | |
echo -n > php-support.md.ed | |
for f in section-*.md; do | |
# find first and last line of the section file | |
first=$(head -n1 "$f") | |
last=$(tail -n1 "$f") | |
# grep the line numbers (-n) as fixed (-F) full-line (-x) strings and extract them | |
start=$(grep -nFx "$first" php-support.md | cut -d':' -f1) | |
end=$(grep -nFx "$last" php-support.md | cut -d':' -f1) | |
# write out an ed command that says "from starting line to ending line, replace with what follows" | |
# (patch will handle the line numbers correctly even if they're not ordered with changes at end of file coming first) | |
echo "${start},${end}c" >> php-support.md.ed | |
# write out new contents for range in command above | |
cat "$f" >> php-support.md.ed | |
# mark end of content | |
echo "." >> php-support.md.ed | |
done | |
patch --backup --ed php-support.md php-support.md.ed | |
- name: Dump diff of markdown contents | |
run: | | |
echo '## Diff of changes to ["PHP Support" Dev Center article](https://devcenter.heroku.com/articles/php-support)' >> "$GITHUB_STEP_SUMMARY" | |
echo "${{ inputs.dry-run == true && '**This is based on the source bucket (due to dry-run mode)**, not the production bucket.' || '-n' }}" >> "$GITHUB_STEP_SUMMARY" | |
echo '```diff' >> "$GITHUB_STEP_SUMMARY" | |
diff -u php-support.md.orig php-support.md | |
echo '```' >> "$GITHUB_STEP_SUMMARY" | |
- name: Output complete Dev Center article markdown | |
run: | | |
echo '## Updated markdown for ["PHP Support" Dev Center article](https://devcenter.heroku.com/articles/php-support)' >> "$GITHUB_STEP_SUMMARY" | |
echo "${{ inputs.dry-run == true && '**This is based on the source bucket (due to dry-run mode)**, not the production bucket.' || '-n' }}" >> "$GITHUB_STEP_SUMMARY" | |
echo '```markdown' >> "$GITHUB_STEP_SUMMARY" | |
# convert back to the original CRLF if dos2unix ran in an earlier step | |
cat have_crlf.txt | xargs -r0 unix2dos | |
echo '```' >> "$GITHUB_STEP_SUMMARY" |