Code Check workflow (aisingapore/TagUI)
The Code Check workflow from aisingapore/TagUI, explained and optimized by Latchkey.
CI health: F - at risk
Run this on Latchkey for self-healing, caching, and up to 58% lower cost.
Grade your own workflow free or run it on Latchkey →What it does
This is the Code Check workflow from the aisingapore/TagUI repository, a real project running GitHub Actions. It is shown here with attribution under its Apache-2.0 license.
Below, Latchkey shows a faster, safer version produced by its optimization engine.
The workflow
name: Code Check
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
workflow_call:
workflow_dispatch:
jobs:
code_check:
strategy:
matrix:
os: [windows-latest, macOS-latest, ubuntu-latest]
runs-on: ${{ matrix.os }}
outputs:
output1: ${{ steps.compare_output_windows.outputs.diff }}
output2: ${{ steps.compare_output_macos_linux.outputs.diff }}
steps:
# Checks-out repository under $GITHUB_WORKSPACE, so job can access it
- uses: actions/checkout@v3
# Setup Amazon Coretto OpenJDK
- uses: actions/setup-java@v3
with:
distribution: 'corretto'
java-version: '8'
- name: Install Microsoft Visual C++ Redistributable using chocolatey (Windows)
if: (matrix.os == 'windows-latest')
uses: crazy-max/ghaction-chocolatey@v1
with:
args: install vcredist2012
- name: Install TagUI (Windows)
if: (matrix.os == 'windows-latest')
run: |
# Add src to path variable
echo "${{github.workspace}}\src" >> $env:GITHUB_PATH
# Add tagui_logging file for generated js file to persist
Out-File -FilePath "${{github.workspace}}\src\tagui_logging"
- name: Install TagUI (macOS / Linux)
if: (matrix.os != 'windows-latest')
run: |
# Add src to path variable
sudo ln -sf ${{github.workspace}}/src/tagui /usr/local/bin/tagui
# Add tagui_logging file for generated js file to persist
cd "${{github.workspace}}/src"
touch tagui_logging
chmod -R 777 "${{github.workspace}}"
- name: Add Unx, PHP, CasperJS and SlimerJS dependency files (Windows)
if: (matrix.os == 'windows-latest')
run: |
cd "${{github.workspace}}\src"
# Add unx dependencies
Invoke-WebRequest -Uri 'https://storage.googleapis.com/tagui-dependencies/unx.zip' -OutFile unxzip.zip
Expand-Archive -LiteralPath unxzip.zip
MOVE-ITEM -Path "${{github.workspace}}\src\unxzip\*" -Destination "${{github.workspace}}\src"
Remove-Item unxzip.zip
# Add PHP dependency files
Invoke-WebRequest 'https://windows.php.net/downloads/releases/archives/php-5.6.30-Win32-VC11-x86.zip' -OutFile php.zip
Expand-Archive -LiteralPath php.zip
Remove-Item php.zip
# Add SikuliX dependency files
Invoke-WebRequest -Uri 'https://storage.googleapis.com/tagui-dependencies/sikulix.zip' -OutFile sikulixzip.zip
Expand-Archive -LiteralPath sikulixzip.zip
MOVE-ITEM -Path "${{github.workspace}}\src\sikulixzip\*" -Destination "${{github.workspace}}\src"
Remove-Item sikulixzip.zip
# Add CasperJS dependency files
Invoke-WebRequest 'https://github.com/casperjs/casperjs/archive/refs/tags/1.1.4-1.zip' -OutFile casperjszip.zip
Expand-Archive -LiteralPath casperjszip.zip
MOVE-ITEM -Path "${{github.workspace}}\src\casperjszip\*" -Destination "${{github.workspace}}\src"
Remove-Item casperjszip.zip
Rename-Item -Path '${{github.workspace}}\src\casperjs-1.1.4-1' -NewName '${{github.workspace}}\src\casperjs'
# Add SlimerJS dependency files
Invoke-WebRequest 'https://github.com/laurentj/slimerjs/releases/download/1.0.0/slimerjs-1.0.0.zip' -OutFile slimerjszip.zip
Expand-Archive -LiteralPath slimerjszip.zip
MOVE-ITEM -Path "${{github.workspace}}\src\slimerjszip\*" -Destination "${{github.workspace}}\src"
Remove-Item slimerjszip.zip
Rename-Item -Path '${{github.workspace}}\src\slimerjs-1.0.0' -NewName '${{github.workspace}}\src\slimerjs'
# Add PhantomJS dependency files
Invoke-WebRequest 'https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-windows.zip' -OutFile phantomjszip.zip
Expand-Archive -LiteralPath phantomjszip.zip
MOVE-ITEM -Path "${{github.workspace}}\src\phantomjszip\*" -Destination "${{github.workspace}}\src"
Remove-Item phantomjszip.zip
Rename-Item -Path '${{github.workspace}}\src\phantomjs-2.1.1-windows' -NewName '${{github.workspace}}\src\phantomjs'
- name: Add SikuliX, CasperJS and SlimerJS dependency files (macOS / Linux)
if: (matrix.os != 'windows-latest')
run: |
cd "${{github.workspace}}/src"
# Add SikuliX dependency files
curl -L 'https://storage.googleapis.com/tagui-dependencies/sikulix.zip' > sikulixzip.zip
unzip sikulixzip.zip
rm sikulixzip.zip
# Add CasperJS dependency files
curl -L 'https://github.com/casperjs/casperjs/archive/refs/tags/1.1.4-1.zip' > casperjs.zip
unzip casperjs.zip
rm casperjs.zip
mv casperjs-1.1.4-1 casperjs
# Add SlimerJS dependency files
curl -L 'https://github.com/laurentj/slimerjs/releases/download/1.0.0/slimerjs-1.0.0.zip' > slimerjs.zip
unzip slimerjs.zip
rm slimerjs.zip
mv slimerjs-1.0.0 slimerjs
- name: Add PhantomJS dependency files (macOS)
if: (matrix.os == 'macOS-latest')
run: |
cd "${{github.workspace}}/src"
curl -L 'https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-macosx.zip' > phantomjs.zip
unzip phantomjs.zip
rm phantomjs.zip
mv phantomjs-2.1.1-macosx phantomjs
- name: Add PhantomJS dependency files (Linux)
if: (matrix.os == 'ubuntu-latest')
run: |
cd "${{github.workspace}}/src"
curl -L 'https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2' > phantomjs.tar.bz2
tar -xf phantomjs.tar.bz2
rm phantomjs.tar.bz2
mv phantomjs-2.1.1-linux-x86_64 phantomjs
- name: Run visual automation flow for first time to install jython standalone jar - expected to fail (Windows)
if: (matrix.os == 'windows-latest')
timeout-minutes: 2
continue-on-error: true
run:
tagui "${{github.workspace}}\src\test\positive_test.tag" -n
- name: Run visual automation flow again for successful run (Windows)
if: (matrix.os == 'windows-latest')
run:
tagui "${{github.workspace}}\src\test\positive_test.tag" -n
- name: Run visual automation flow for first time to install jython standalone jar - expected to fail (macOS / Linux)
if: (matrix.os != 'windows-latest')
timeout-minutes: 2
continue-on-error: true
run:
tagui "${{github.workspace}}/src/test/positive_test.tag" -n
- name: Run visual automation flow again for successful run (macOS / Linux)
if: (matrix.os != 'windows-latest')
run:
tagui "${{github.workspace}}/src/test/positive_test.tag" -n
- name: Compare output of positive_test.js and positive_test.signature (Windows)
if: (matrix.os == 'windows-latest')
id: compare_output_windows
run: |
Compare-Object (Get-Content '${{github.workspace}}\src\test\positive_test.js') (Get-Content '${{github.workspace}}\src\test\positive_test.signature') -PassThru | Set-Content '${{github.workspace}}\src\test\output.txt'
if(Test-Path -Path '${{github.workspace}}\src\test\output.txt' -PathType Leaf) {exit 1}
- name: Compare output of positive_test.js and positive_test.signature (macOS / Linux)
if: (matrix.os != 'windows-latest')
id: compare_output_macos_linux
run:
if ! diff "${{github.workspace}}/src/test/positive_test.js" "${{github.workspace}}/src/test/positive_test.signature" >/dev/null; then exit 1; fi
The same workflow, on Latchkey
Estimated ~20% faster on cache hits, plus fewer wasted runs and a safer supply chain. Added and changed lines are highlighted.
name: Code Check on: push: branches: [ master ] pull_request: branches: [ master ] workflow_call: workflow_dispatch: concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: code_check: timeout-minutes: 30 strategy: matrix: os: [windows-latest, macOS-latest, ubuntu-latest] runs-on: ${{ matrix.os }} outputs: output1: ${{ steps.compare_output_windows.outputs.diff }} output2: ${{ steps.compare_output_macos_linux.outputs.diff }} steps: # Checks-out repository under $GITHUB_WORKSPACE, so job can access it - uses: actions/checkout@v3 # Setup Amazon Coretto OpenJDK - uses: actions/setup-java@v3 with: cache: 'maven' distribution: 'corretto' java-version: '8' - name: Install Microsoft Visual C++ Redistributable using chocolatey (Windows) if: (matrix.os == 'windows-latest') uses: crazy-max/ghaction-chocolatey@v1 with: args: install vcredist2012 - name: Install TagUI (Windows) if: (matrix.os == 'windows-latest') run: | # Add src to path variable echo "${{github.workspace}}\src" >> $env:GITHUB_PATH # Add tagui_logging file for generated js file to persist Out-File -FilePath "${{github.workspace}}\src\tagui_logging" - name: Install TagUI (macOS / Linux) if: (matrix.os != 'windows-latest') run: | # Add src to path variable sudo ln -sf ${{github.workspace}}/src/tagui /usr/local/bin/tagui # Add tagui_logging file for generated js file to persist cd "${{github.workspace}}/src" touch tagui_logging chmod -R 777 "${{github.workspace}}" - name: Add Unx, PHP, CasperJS and SlimerJS dependency files (Windows) if: (matrix.os == 'windows-latest') run: | cd "${{github.workspace}}\src" # Add unx dependencies Invoke-WebRequest -Uri 'https://storage.googleapis.com/tagui-dependencies/unx.zip' -OutFile unxzip.zip Expand-Archive -LiteralPath unxzip.zip MOVE-ITEM -Path "${{github.workspace}}\src\unxzip\*" -Destination "${{github.workspace}}\src" Remove-Item unxzip.zip # Add PHP dependency files Invoke-WebRequest 'https://windows.php.net/downloads/releases/archives/php-5.6.30-Win32-VC11-x86.zip' -OutFile php.zip Expand-Archive -LiteralPath php.zip Remove-Item php.zip # Add SikuliX dependency files Invoke-WebRequest -Uri 'https://storage.googleapis.com/tagui-dependencies/sikulix.zip' -OutFile sikulixzip.zip Expand-Archive -LiteralPath sikulixzip.zip MOVE-ITEM -Path "${{github.workspace}}\src\sikulixzip\*" -Destination "${{github.workspace}}\src" Remove-Item sikulixzip.zip # Add CasperJS dependency files Invoke-WebRequest 'https://github.com/casperjs/casperjs/archive/refs/tags/1.1.4-1.zip' -OutFile casperjszip.zip Expand-Archive -LiteralPath casperjszip.zip MOVE-ITEM -Path "${{github.workspace}}\src\casperjszip\*" -Destination "${{github.workspace}}\src" Remove-Item casperjszip.zip Rename-Item -Path '${{github.workspace}}\src\casperjs-1.1.4-1' -NewName '${{github.workspace}}\src\casperjs' # Add SlimerJS dependency files Invoke-WebRequest 'https://github.com/laurentj/slimerjs/releases/download/1.0.0/slimerjs-1.0.0.zip' -OutFile slimerjszip.zip Expand-Archive -LiteralPath slimerjszip.zip MOVE-ITEM -Path "${{github.workspace}}\src\slimerjszip\*" -Destination "${{github.workspace}}\src" Remove-Item slimerjszip.zip Rename-Item -Path '${{github.workspace}}\src\slimerjs-1.0.0' -NewName '${{github.workspace}}\src\slimerjs' # Add PhantomJS dependency files Invoke-WebRequest 'https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-windows.zip' -OutFile phantomjszip.zip Expand-Archive -LiteralPath phantomjszip.zip MOVE-ITEM -Path "${{github.workspace}}\src\phantomjszip\*" -Destination "${{github.workspace}}\src" Remove-Item phantomjszip.zip Rename-Item -Path '${{github.workspace}}\src\phantomjs-2.1.1-windows' -NewName '${{github.workspace}}\src\phantomjs' - name: Add SikuliX, CasperJS and SlimerJS dependency files (macOS / Linux) if: (matrix.os != 'windows-latest') run: | cd "${{github.workspace}}/src" # Add SikuliX dependency files curl -L 'https://storage.googleapis.com/tagui-dependencies/sikulix.zip' > sikulixzip.zip unzip sikulixzip.zip rm sikulixzip.zip # Add CasperJS dependency files curl -L 'https://github.com/casperjs/casperjs/archive/refs/tags/1.1.4-1.zip' > casperjs.zip unzip casperjs.zip rm casperjs.zip mv casperjs-1.1.4-1 casperjs # Add SlimerJS dependency files curl -L 'https://github.com/laurentj/slimerjs/releases/download/1.0.0/slimerjs-1.0.0.zip' > slimerjs.zip unzip slimerjs.zip rm slimerjs.zip mv slimerjs-1.0.0 slimerjs - name: Add PhantomJS dependency files (macOS) if: (matrix.os == 'macOS-latest') run: | cd "${{github.workspace}}/src" curl -L 'https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-macosx.zip' > phantomjs.zip unzip phantomjs.zip rm phantomjs.zip mv phantomjs-2.1.1-macosx phantomjs - name: Add PhantomJS dependency files (Linux) if: (matrix.os == 'ubuntu-latest') run: | cd "${{github.workspace}}/src" curl -L 'https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2' > phantomjs.tar.bz2 tar -xf phantomjs.tar.bz2 rm phantomjs.tar.bz2 mv phantomjs-2.1.1-linux-x86_64 phantomjs - name: Run visual automation flow for first time to install jython standalone jar - expected to fail (Windows) if: (matrix.os == 'windows-latest') timeout-minutes: 2 continue-on-error: true run: tagui "${{github.workspace}}\src\test\positive_test.tag" -n - name: Run visual automation flow again for successful run (Windows) if: (matrix.os == 'windows-latest') run: tagui "${{github.workspace}}\src\test\positive_test.tag" -n - name: Run visual automation flow for first time to install jython standalone jar - expected to fail (macOS / Linux) if: (matrix.os != 'windows-latest') timeout-minutes: 2 continue-on-error: true run: tagui "${{github.workspace}}/src/test/positive_test.tag" -n - name: Run visual automation flow again for successful run (macOS / Linux) if: (matrix.os != 'windows-latest') run: tagui "${{github.workspace}}/src/test/positive_test.tag" -n - name: Compare output of positive_test.js and positive_test.signature (Windows) if: (matrix.os == 'windows-latest') id: compare_output_windows run: | Compare-Object (Get-Content '${{github.workspace}}\src\test\positive_test.js') (Get-Content '${{github.workspace}}\src\test\positive_test.signature') -PassThru | Set-Content '${{github.workspace}}\src\test\output.txt' if(Test-Path -Path '${{github.workspace}}\src\test\output.txt' -PathType Leaf) {exit 1} - name: Compare output of positive_test.js and positive_test.signature (macOS / Linux) if: (matrix.os != 'windows-latest') id: compare_output_macos_linux run: if ! diff "${{github.workspace}}/src/test/positive_test.js" "${{github.workspace}}/src/test/positive_test.signature" >/dev/null; then exit 1; fi
What changed
- Cancel superseded runs when a branch or PR gets a newer push.
- Cache dependency installs on the setup step so they are served from cache.
- Add a job timeout so a hung step cannot burn hours of runner time.
1 third-party action is referenced by a movable tag. Pin it to the commit SHA (Latchkey resolves and applies this automatically) so a repointed tag cannot change what runs.
What Latchkey heals here
This workflow has steps that commonly fail on transient issues (network, registries, flaky browsers). On Latchkey managed runners they are detected, retried, and self-healed instead of failing your build:
- Network fetches
This workflow runs 1 job (3 with the matrix expanded) per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.