Skip to content

Commit

Permalink
Run Lighthouse against a local server per push (#216)
Browse files Browse the repository at this point in the history
  • Loading branch information
bollwyvl authored Jul 9, 2020
1 parent df85690 commit 2cb2bed
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 19 deletions.
17 changes: 0 additions & 17 deletions .github/workflows/artifact.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,3 @@ jobs:
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
artifact-path: 0/html/index.html
- name: Wait Until Site is Ready
run: |
curl --retry 10 --retry-connrefused --retry-max-time 60 ${{ steps.redirect.outputs.url }}
- name: Make folder for Lighthouse reports
run: mkdir /tmp/lighthouse
- name: Run Lighthouse on Site
id: lighthouse
uses: foo-software/lighthouse-check-action@v2.0.0
with:
urls: ${{ steps.redirect.outputs.url }}
outputDirectory: /tmp/lighthouse
verbose: true
- name: Upload Lighthouse Reports
uses: actions/upload-artifact@v2
with:
name: Lighthouse Report ${{ github.run_number }}
path: /tmp/lighthouse
76 changes: 74 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,12 @@ jobs:
python -m pip install --upgrade pip
python -m pip install --upgrade pre-commit
pip install -e .
yarn install
yarn
- name: Lint
run: |
pre-commit run --all-files
# Build docs on a number of Python versions. In the future this can be
# where tests go.
tests:
Expand Down Expand Up @@ -63,6 +62,79 @@ jobs:
export PATH="$HOME/miniconda/bin:$PATH"
sphinx-build -b html docs/ docs/_build/html -W --keep-going
# Run local Lighthouse audit against built site
audit:

runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.8]
env:
PORT: 8000
# the host interface to listen on, might need to be 0.0.0.0
HOST: 127.0.0.1
# the base url
URL: http://127.0.0.1:8000

steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v1
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e .
pip install -r docs/requirements.txt
# Build the docs
- name: Build docs to store
run: |
export PATH="$HOME/miniconda/bin:$PATH"
sphinx-build -b html docs/ docs/_build/html -W --keep-going
# Serve the docs and wait to be ready
- name: Serve the built site
run: |
nohup python docs/serve.py --port=${PORT} --host=${HOST} &
curl --retry 10 --retry-connrefused --retry-max-time 60 ${URL}/index.html
# Run the audit
# TODO: use the hosted API with a secret? would allow for comparison over time...
- name: Make folder for Lighthouse reports
run: mkdir -p /tmp/lighthouse/lighthouse-${{ github.run_number }}
- name: Run Lighthouse on Site
id: lighthouse
uses: foo-software/lighthouse-check-action@v2.0.0
with:
# TODO: generate this list to audit all html pages
urls: >-
${{ env.URL }}/index.html,
${{ env.URL }}/demo/api.html,
${{ env.URL }}/demo/demo.html,
${{ env.URL }}/demo/example_pandas.html
outputDirectory: /tmp/lighthouse/lighthouse-${{ github.run_number }}
verbose: true

# Store the audit
- name: Upload Lighthouse Reports
uses: actions/upload-artifact@v2
with:
name: Lighthouse Report ${{ github.run_number }}
path: /tmp/lighthouse

# Check the audit for threshold values
# TODO: write this someplace after a PR is merged, and load?
- name: Assess Lighthouse Check results
uses: foo-software/lighthouse-check-status-action@v1.0.1
with:
lighthouseCheckResults: ${{ steps.lighthouse.outputs.lighthouseCheckResults }}
minAccessibilityScore: "96"
minBestPracticesScore: "90"
minPerformanceScore: "10"
minSeoScore: "80"

publish:

name: Publish to PyPi
Expand Down
60 changes: 60 additions & 0 deletions docs/serve.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
""" a minimal static server, primarily for performing audits
this is not meant to be used in production, and some settings are insecure
to game auditing metrics which will vary substantially by deployment
"""
from pathlib import Path
from tornado import ioloop, web, options

options.define("port", default=8080, help="port to listen on")
options.define(
"host", default="localhost", help="host interface to connect on (0.0.0.0 is all)"
)

SETTINGS = dict(
static_path=Path(__file__).parent / "_build/html",
# enabling compression can have security impacts if not done correctly
compress_response=True,
# not really useful for production
autoreload=True,
)


class CacheStaticHandler(web.StaticFileHandler):
def get_cache_time(self, *args, **kwargs):
""" always return a fairly long time. real deployments would have a more
robust solution
"""
return int(1e10)


def make_app():
""" create and return (but do not start) a tornado app
"""
app = web.Application(
[(r"^/(.*)", CacheStaticHandler, dict(path=SETTINGS["static_path"]))],
**SETTINGS
)

return app


def main(port, host):
""" start a tornado app on the desired port
"""
app = make_app()
app.listen(port, host)
url = "http://{}:{}/".format(host, port)
print("Watching files: \t\t{static_path}".format(**SETTINGS))
print("Hosting site on:\t\t{}".format(url))
print("\nPress `Ctrl+C` to stop")
try:
ioloop.IOLoop.current().start()
except KeyboardInterrupt:
ioloop.IOLoop.current().stop()
print("The server was stopped")


if __name__ == "__main__":
options.parse_command_line()
main(port=options.options.port, host=options.options.host)

0 comments on commit 2cb2bed

Please sign in to comment.