Ensure all API endpoints are safe against uncaught promise rejections #116
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: Build and Test | |
on: | |
push: | |
branches: | |
- '**' | |
pull_request: | |
branches: | |
- main | |
workflow_dispatch: {} | |
jobs: | |
build_and_test: | |
runs-on: ubuntu-latest | |
timeout-minutes: 20 | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Install Node | |
uses: actions/setup-node@v4 | |
with: | |
node-version: '22' | |
cache: npm | |
cache-dependency-path: | | |
backend/package-lock.json | |
frontend/package-lock.json | |
e2e/package-lock.json | |
- name: Build and Test | |
run: PARALLEL_BUILD=false PARALLEL_E2E=false EXPLICIT_WAIT_TIMEOUT=20000 TEST_TIMEOUT=60000 npm test | |
- name: Bundle | |
run: | | |
cd build | |
rm -r node_modules | |
tar -czf ../build.tar.gz . | |
- name: Upload Bundle | |
uses: actions/upload-artifact@v4 | |
with: | |
name: refacto | |
retention-days: 1 | |
if-no-files-found: error | |
path: build.tar.gz | |
smoke_test: | |
needs: | |
- build_and_test | |
runs-on: ubuntu-latest | |
timeout-minutes: 10 | |
strategy: | |
fail-fast: false | |
matrix: | |
include: | |
- { node: '18' } | |
- { node: '20' } | |
- { node: '22' } | |
- { node: '23' } | |
steps: | |
- name: Install Node | |
uses: actions/setup-node@v4 | |
with: | |
node-version: ${{ matrix.node }} | |
- name: Download Bundle | |
uses: actions/download-artifact@v4 | |
with: | |
name: refacto | |
- name: Unpack | |
run: tar -xf build.tar.gz && rm build.tar.gz | |
- name: Smoke Test | |
run: | | |
set -e; | |
npm install --omit=dev; | |
./index.js > output.log 2>&1 & APP_PID="$!"; | |
while [ ! -f output.log ] || ! grep 'Available at' < output.log > /dev/null 2>&1; do | |
if ! ps -p "$APP_PID" > /dev/null; then | |
APP_EXIT_CODE="$(wait "$APP_PID" > /dev/null; echo "$?")"; | |
cat output.log; | |
echo "Application failed to launch (exit code: $APP_EXIT_CODE)."; | |
false; | |
fi; | |
sleep 0.1; | |
done; | |
wget localhost:5000 -O test-index.html; | |
if ! grep '<title>Refacto</title>' < test-index.html > /dev/null; then | |
cat output.log; | |
echo "Unexpected main page response" >&2; | |
cat test-index.html; | |
false; | |
fi; | |
kill -2 "$APP_PID"; | |
wait "$APP_PID"; | |
if ! grep 'Shutdown complete' < output.log > /dev/null; then | |
cat output.log; | |
echo "Application failed to shut down" >&2; | |
false; | |
fi; | |
create_release: | |
needs: | |
- smoke_test | |
runs-on: ubuntu-latest | |
timeout-minutes: 10 | |
if: ${{ github.ref == 'refs/heads/main' && github.head_ref == null }} | |
permissions: | |
contents: write | |
steps: | |
- name: Download Bundle | |
uses: actions/download-artifact@v4 | |
with: | |
name: refacto | |
- name: Create Release | |
env: | |
API_BASE: 'https://api.github.com/repos/${{ github.repository }}' | |
COMMIT: ${{ github.sha }} | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
run: | | |
set -e; | |
NAME="$(date -u '+%Y%m%d-%H%M%S')"; | |
echo "Creating release $NAME..."; | |
wget -S \ | |
--header='Accept: application/vnd.github.v3+json' \ | |
--header="Authorization: token $GITHUB_TOKEN" \ | |
--post-data="$(jq -n --arg n "$NAME" --arg c "$COMMIT" '{tag_name: $n, target_commitish: $c}')" \ | |
"$API_BASE/releases" -O release.json; | |
cat release.json; | |
echo "Uploading bundle..."; | |
UPLOAD_URL="$(jq -r '.upload_url' < release.json | sed 's/{[^}]*}//')"; | |
wget -S \ | |
--header='Accept: application/vnd.github.v3+json' \ | |
--header="Authorization: token $GITHUB_TOKEN" \ | |
--header='Content-Type: application/gzip' \ | |
--post-file='build.tar.gz' \ | |
"$UPLOAD_URL?name=build.tar.gz" -O release-file.json; | |
cat release-file.json; | |
echo "Done."; |