Skip to content

Workflow file for this run

name: Continuous Integration & Deployment
on: [push]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
packages: write
jobs:
api-test:
name: "API πŸ“‘ - test πŸ§ͺ"
runs-on: ubuntu-latest
env:
RAILS_ENV: test
TEST_DATABASE_URL: mysql2://root:[email protected]:3306/dolos_test
services:
mysql:
image: mariadb
env:
MARIADB_ROOT_PASSWORD: dolos
MARIADB_DATABASE: dolos_test
MARIADB_HOST: localhost
MARIADB_MYSQL_LOCALHOST_USER: 1
MARIADB_MYSQL_LOCALHOST_GRANTS: USAGE
ports:
- 3306:3306
options: --health-cmd="healthcheck.sh --su-mysql --connect --innodb_initialized" --health-interval=10s --health-timeout=5s --health-retries=5
steps:
- name: Checkout πŸ›ŽοΈ
uses: actions/checkout@v4
- name: Setup Ruby πŸ“š
uses: ruby/setup-ruby@v1
with:
working-directory: api/
bundler-cache: true
- name: Run tests πŸ§ͺ
run: |
cd api/
docker pull ghcr.io/dodona-edu/dolos-cli:latest
bundle exec rails db:prepare
bundle exec rails test
api-lint:
name: "API πŸ“‘ - lint πŸ“"
runs-on: ubuntu-latest
steps:
- name: Checkout πŸ›ŽοΈ
uses: actions/checkout@v4
- name: Setup Ruby πŸ“š
uses: ruby/setup-ruby@v1
with:
working-directory: api/
bundler-cache: true
- name: Run rubocop πŸ“
run: |
cd api/
bundle exec rubocop
install-deps:
name: Install (Node ${{ matrix.node }}) ⚑️
runs-on: ubuntu-latest
strategy:
matrix:
node: [ "18", "20", "22" ]
fail-fast: false
steps:
- name: Checkout πŸ›ŽοΈ
uses: actions/checkout@v4
with:
submodules: true
- name: Cache npm dependencies
id: cache-dependencies
uses: actions/cache@v4
with:
path: |
${{ github.workspace }}/node_modules
${{ github.workspace }}/*/node_modules
${{ github.workspace }}/parsers/build
key: ${{ runner.os }}-node-${{ matrix.node }}-${{ hashFiles('./package-lock.json', './package.json', './*/package.json', './parsers/binding.gyp', './.gitmodules') }}
- name: Setup Node πŸ“š
if: steps.cache-dependencies.outputs.cache-hit != 'true'
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- name: Npm install ⚑️
if: steps.cache-dependencies.outputs.cache-hit != 'true'
run: npm install
cli-build:
name: "CLI πŸ’»οΈ - build πŸ”§"
runs-on: ubuntu-latest
needs: install-deps
strategy:
matrix:
node: [ "18", "20", "22" ]
fail-fast: false
steps:
- name: Checkout πŸ›ŽοΈ
uses: actions/checkout@v4
with:
submodules: true
- name: Setup Node πŸ“š
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- name: Fetch Dependencies ⚑️
id: cache-dependencies
uses: actions/cache@v4
with:
path: |
${{ github.workspace }}/node_modules
${{ github.workspace }}/*/node_modules
${{ github.workspace }}/parsers/build
key: ${{ runner.os }}-node-${{ matrix.node }}-${{ hashFiles('./package-lock.json', './package.json', './*/package.json', './parsers/binding.gyp', './.gitmodules') }}
- name: Check if cache was hit πŸ”Ž
if: steps.cache-dependencies.outputs.cache-hit != 'true'
run: |
echo "Should have hit cache"
false
- name: Build πŸ”§
run: |
cd cli/
npm run build -- --force
cli-lint:
name: "CLI πŸ’»οΈ - lint πŸ“"
runs-on: ubuntu-latest
needs: install-deps
strategy:
matrix:
node: [ "22" ]
fail-fast: false
steps:
- name: Checkout πŸ›ŽοΈ
uses: actions/checkout@v4
- name: Setup Node πŸ“š
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- name: Fetch Dependencies ⚑️
id: cache-dependencies
uses: actions/cache@v4
with:
path: |
${{ github.workspace }}/node_modules
${{ github.workspace }}/*/node_modules
${{ github.workspace }}/parsers/build
key: ${{ runner.os }}-node-${{ matrix.node }}-${{ hashFiles('./package-lock.json', './package.json', './*/package.json', './parsers/binding.gyp', './.gitmodules') }}
- name: Check if cache was hit πŸ”Ž
if: steps.cache-dependencies.outputs.cache-hit != 'true'
run: |
echo "Should have hit cache"
false
- name: Lint πŸ“
run: |
cd cli/
npm run lint
core-build-test:
name: "Core ❀️ - build & test πŸ”§"
runs-on: ubuntu-latest
needs: install-deps
strategy:
matrix:
node: [ "18", "20", "22" ]
fail-fast: false
steps:
- name: Checkout πŸ›ŽοΈ
uses: actions/checkout@v4
- name: Setup Node πŸ“š
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- name: Fetch Dependencies ⚑️
id: cache-dependencies
uses: actions/cache@v4
with:
path: |
${{ github.workspace }}/node_modules
${{ github.workspace }}/*/node_modules
${{ github.workspace }}/parsers/build
key: ${{ runner.os }}-node-${{ matrix.node }}-${{ hashFiles('./package-lock.json', './package.json', './*/package.json', './parsers/binding.gyp', './.gitmodules') }}
- name: Check if cache was hit πŸ”Ž
if: steps.cache-dependencies.outputs.cache-hit != 'true'
run: |
echo "Should have hit cache"
false
- name: Build & test πŸ”§
run: |
cd core/
npm run build
npm run test -- -v --serial
core-lint:
name: "Core ❀️ - lint πŸ“"
runs-on: ubuntu-latest
needs: install-deps
strategy:
matrix:
node: [ "22" ]
fail-fast: false
steps:
- name: Checkout πŸ›ŽοΈ
uses: actions/checkout@v4
- name: Setup Node πŸ“š
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- name: Fetch Dependencies ⚑️
id: cache-dependencies
uses: actions/cache@v4
with:
path: |
${{ github.workspace }}/node_modules
${{ github.workspace }}/*/node_modules
${{ github.workspace }}/parsers/build
key: ${{ runner.os }}-node-${{ matrix.node }}-${{ hashFiles('./package-lock.json', './package.json', './*/package.json', './parsers/binding.gyp', './.gitmodules') }}
- name: Check if cache was hit πŸ”Ž
if: steps.cache-dependencies.outputs.cache-hit != 'true'
run: |
echo "Should have hit cache"
false
- name: Lint πŸ“
run: |
cd core/
npm run lint
lib-build-test:
name: "Lib πŸ“š - build & test πŸ”§"
runs-on: ubuntu-latest
needs: install-deps
strategy:
matrix:
node: [ "18", "20", "22" ]
fail-fast: false
steps:
- name: Checkout πŸ›ŽοΈ
uses: actions/checkout@v4
with:
submodules: true
- name: Setup Node πŸ“š
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- name: Fetch Dependencies ⚑️
id: cache-dependencies
uses: actions/cache@v4
with:
path: |
${{ github.workspace }}/node_modules
${{ github.workspace }}/*/node_modules
${{ github.workspace }}/parsers/build
key: ${{ runner.os }}-node-${{ matrix.node }}-${{ hashFiles('./package-lock.json', './package.json', './*/package.json', './parsers/binding.gyp', './.gitmodules') }}
- name: Check if cache was hit πŸ”Ž
if: steps.cache-dependencies.outputs.cache-hit != 'true'
run: |
echo "Should have hit cache"
false
- name: Build & test πŸ”§
run: |
cd lib/
npm run build
npm run test -- -v --serial
parsers-build:
name: "Parsers πŸ‘“ - build πŸ”§"
runs-on: ubuntu-latest
needs: install-deps
strategy:
matrix:
node: [ "18", "20", "22" ]
fail-fast: false
steps:
- name: Checkout πŸ›ŽοΈ
uses: actions/checkout@v4
with:
submodules: true
- name: Setup Node πŸ“š
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- name: Fetch Dependencies ⚑️
id: cache-dependencies
uses: actions/cache@v4
with:
path: |
${{ github.workspace }}/node_modules
${{ github.workspace }}/*/node_modules
${{ github.workspace }}/parsers/build
key: ${{ runner.os }}-node-${{ matrix.node }}-${{ hashFiles('./package-lock.json', './package.json', './*/package.json', './parsers/binding.gyp', './.gitmodules') }}
- name: Check if cache was hit πŸ”Ž
if: steps.cache-dependencies.outputs.cache-hit != 'true'
run: |
echo "Should have hit cache"
false
- name: Build πŸ”§
run: |
cd parsers/
npm run build
lib-lint:
name: "Lib πŸ“š - lint πŸ“"
runs-on: ubuntu-latest
needs: install-deps
strategy:
matrix:
node: [ "22" ]
fail-fast: false
steps:
- name: Checkout πŸ›ŽοΈ
uses: actions/checkout@v4
- name: Setup Node πŸ“š
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- name: Fetch Dependencies ⚑️
id: cache-dependencies
uses: actions/cache@v4
with:
path: |
${{ github.workspace }}/node_modules
${{ github.workspace }}/*/node_modules
${{ github.workspace }}/parsers/build
key: ${{ runner.os }}-node-${{ matrix.node }}-${{ hashFiles('./package-lock.json', './package.json', './*/package.json', './parsers/binding.gyp', './.gitmodules') }}
- name: Check if cache was hit πŸ”Ž
if: steps.cache-dependencies.outputs.cache-hit != 'true'
run: |
echo "Should have hit cache"
false
- name: Lint πŸ“
run: |
cd lib/
npm run lint
web-build-deploy:
name: "Web 🌐 - build & deploy πŸ”§"
runs-on: ubuntu-latest
needs: install-deps
strategy:
matrix:
node: [ "22" ]
fail-fast: false
steps:
- name: Checkout πŸ›ŽοΈ
uses: actions/checkout@v4
with:
submodules: true
- name: Setup Node πŸ“š
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- name: Fetch Dependencies ⚑️
id: cache-dependencies
uses: actions/cache@v4
with:
path: |
${{ github.workspace }}/node_modules
${{ github.workspace }}/*/node_modules
${{ github.workspace }}/parsers/build
key: ${{ runner.os }}-node-${{ matrix.node }}-${{ hashFiles('./package-lock.json', './package.json', './*/package.json', './parsers/binding.gyp', './.gitmodules') }}
- name: Check if cache was hit πŸ”Ž
if: steps.cache-dependencies.outputs.cache-hit != 'true'
run: |
echo "Should have hit cache"
false
- name: Build core πŸ”§
run: |
cd core/
npm run build
- name: Build web πŸ”§
run: |
cd web/
npm run build
- name: Deploy to staging πŸš€
run: |
if [ -n "$KNOWN_HOSTS" ]; then
cd web/
mkdir -p ~/.ssh
echo "$SSH_KEY" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
echo "$KNOWN_HOSTS" > ~/.ssh/known_hosts
chmod 600 ~/.ssh/known_hosts
mkdir -p "deploy/$REF"
cp -a dist/. "deploy/$REF"
rsync -glpPrtvz \
--relative \
--delete \
-e 'ssh -p 4840' \
"deploy/./$REF" \
"[email protected]:web/"
else
echo "Skipping deploy because secrets are not available"
fi
env:
SSH_KEY: ${{ secrets.SSH_KEY }}
KNOWN_HOSTS: ${{ secrets.KNOWN_HOSTS }}
REF: ${{ github.ref_name }}
web-lint:
name: "Web 🌐 - lint πŸ“"
runs-on: ubuntu-latest
needs: install-deps
strategy:
matrix:
node: [ "22" ]
fail-fast: false
steps:
- name: Checkout πŸ›ŽοΈ
uses: actions/checkout@v4
- name: Setup Node πŸ“š
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- name: Fetch Dependencies ⚑️
id: cache-dependencies
uses: actions/cache@v4
with:
path: |
${{ github.workspace }}/node_modules
${{ github.workspace }}/*/node_modules
${{ github.workspace }}/parsers/build
key: ${{ runner.os }}-node-${{ matrix.node }}-${{ hashFiles('./package-lock.json', './package.json', './*/package.json', './parsers/binding.gyp', './.gitmodules') }}
- name: Check if cache was hit πŸ”Ž
if: steps.cache-dependencies.outputs.cache-hit != 'true'
run: |
echo "Should have hit cache"
false
- name: Lint πŸ“
run: |
cd web/
npm run lint
docs:
name: "Docs πŸ“‘"
runs-on: ubuntu-latest
needs: install-deps
strategy:
matrix:
node: [ "22" ]
fail-fast: false
steps:
- name: Checkout πŸ›ŽοΈ
uses: actions/checkout@v4
- name: Setup Node πŸ“š
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- name: Build πŸ”§
run: |
cd docs/
npm install
npm run build
- name: Deploy πŸš€
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
run: |
if [ -n "$KNOWN_HOSTS" ]; then
cd docs/
mkdir -p ~/.ssh
echo "$SSH_KEY" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
echo "$KNOWN_HOSTS" > ~/.ssh/known_hosts
chmod 600 ~/.ssh/known_hosts
rsync -glpPrtvz \
--delete \
-e 'ssh -p 4840' \
.vitepress/dist/ \
[email protected]:docs
else
echo "Skipping deploy because secrets are not available"
fi
env:
SSH_KEY: ${{ secrets.SSH_KEY }}
KNOWN_HOSTS: ${{ secrets.KNOWN_HOSTS }}
publish:
name: "Publish packages on NPM πŸ“¦"
runs-on: ubuntu-latest
needs: install-deps
if: startsWith(github.ref, 'refs/tags/v')
strategy:
matrix:
node: [ "22" ]
fail-fast: false
steps:
- name: Checkout πŸ›ŽοΈ
uses: actions/checkout@v4
with:
submodules: true
- name: Setup Node πŸ“š
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- name: Fetch Dependencies ⚑️
id: cache-dependencies
uses: actions/cache@v4
with:
path: |
${{ github.workspace }}/node_modules
${{ github.workspace }}/*/node_modules
${{ github.workspace }}/parsers/build
key: ${{ runner.os }}-node-${{ matrix.node }}-${{ hashFiles('./package-lock.json', './package.json', './*/package.json', './parsers/binding.gyp', './.gitmodules') }}
- name: Check if cache was hit πŸ”Ž
if: steps.cache-dependencies.outputs.cache-hit != 'true'
run: |
echo "Should have hit cache"
false
- name: Parse tag
id: parse_tag
run: "echo ${{ github.ref }} | sed 's#^refs/tags/#version=#' >> $GITHUB_OUTPUT"
- name: Draft release
id: create_release
uses: release-drafter/release-drafter@v6
with:
name: ${{ steps.parse_tag.outputs.version }}
tag: ${{ steps.parse_tag.outputs.version }}
version: ${{ steps.parse_tag.outputs.version }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build core πŸ”§
run: |
cd core/
npm run build
- name: Build parsers πŸ”§
run: |
cd parsers/
npm run build
- name: Build lib πŸ”§
run: |
cd lib/
npm run build
- name: Build CLI πŸ”§
run: |
cd cli/
npm run build -- --force
- name: Build web πŸ”§
run: |
cd web/
npm run build
- name: Publish @dodona/dolos-core to NPM
uses: JS-DevTools/npm-publish@v3
with:
token: ${{ secrets.NPM_AUTH_TOKEN }}
package: ./core/package.json
strategy: all
access: public
- name: Publish @dodona/dolos-parsers to NPM
uses: JS-DevTools/npm-publish@v3
with:
token: ${{ secrets.NPM_AUTH_TOKEN }}
package: ./parsers/package.json
strategy: all
access: public
- name: Publish @dodona/dolos-lib to NPM
uses: JS-DevTools/npm-publish@v3
with:
token: ${{ secrets.NPM_AUTH_TOKEN }}
package: ./lib/package.json
strategy: all
access: public
- name: Publish @dodona/dolos-web to NPM
uses: JS-DevTools/npm-publish@v3
with:
token: ${{ secrets.NPM_AUTH_TOKEN }}
package: ./web/package.json
strategy: all
access: public
- name: Publish @dodona/dolos to NPM
uses: JS-DevTools/npm-publish@v3
with:
token: ${{ secrets.NPM_AUTH_TOKEN }}
package: ./cli/package.json
strategy: all
access: public
demo:
name: "Publish demo πŸš€"
needs: publish
runs-on: ubuntu-latest
strategy:
matrix:
node: [ "22" ]
fail-fast: false
steps:
- name: Setup Node πŸ“š
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- name: Install dolos
run: |
npm install -g @dodona/dolos
dolos --version
- name: Setup SSH
run: |
mkdir -p ~/.ssh
echo "$SSH_KEY" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
echo "$KNOWN_HOSTS" > ~/.ssh/known_hosts
chmod 600 ~/.ssh/known_hosts
env:
SSH_KEY: ${{ secrets.SSH_KEY }}
KNOWN_HOSTS: ${{ secrets.KNOWN_HOSTS }}
- name: Prepare analysis
run: |
mkdir analysis
cd analysis
rsync \
-e 'ssh -p 4840' \
[email protected]:demo-datasets.zip \
.
unzip demo-datasets.zip
- name: Run analysis on samples
run: |
cd analysis
dolos -l javascript -f csv -o samples-results samples/info.csv
- name: Run analysis on SOCO Java
run: |
cd analysis
dolos -l java -f csv -o java-results soco/java-labels.csv
- name: Run analysis on SOCO C
run: |
cd analysis
dolos -l c -f csv -o c-results soco/c-labels.csv
- name: Run analysis on Pyramidal constants exercise
run: |
cd analysis
dolos -l python -f csv -o pyramidal-exercise-results "exercise - Pyramidal constants/info.csv"
- name: Run analysis on Pyramidal constants evaluation
run: |
cd analysis
dolos -l python -f csv -o pyramidal-evaluation-results "evaluation - Pyramidal constants/info.csv"
- name: Deploy results to demo site
run: |
cd analysis
npm pack @dodona/dolos-web
tar xzf dodona-dolos-web-*.tgz
mkdir -p demo/sample
mkdir -p demo/soco
mkdir -p demo/pyramidal-constants/exercise
mkdir -p demo/pyramidal-constants/evaluation
cp -r package/dist/. demo/sample
cp -r package/dist/. demo/soco/java
cp -r package/dist/. demo/soco/c
cp -r package/dist/. demo/pyramidal-constants/exercise
cp -r package/dist/. demo/pyramidal-constants/evaluation
cp -r samples-results demo/sample/data
cp -r java-results demo/soco/java/data
cp -r c-results demo/soco/c/data
cp -r pyramidal-exercise-results demo/pyramidal-constants/exercise/data
cp -r pyramidal-evaluation-results demo/pyramidal-constants/evaluation/data
rsync -glpPrtvz \
-e 'ssh -p 4840' \
demo/ \
[email protected]:demo
docker:
name: "Publish docker containers 🚒"
needs: publish
runs-on: ubuntu-latest
permissions:
packages: write
steps:
- name: Checkout πŸ›ŽοΈ
uses: actions/checkout@v4
with:
submodules: true
- name: Setup Node πŸ“š
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- name: Parse tag (without v)
id: parse_tag
run: "echo ${{ github.ref }} | sed 's#^refs/tags/v#version=#' >> $GITHUB_OUTPUT"
- name: Build the Dolos images
run: |
docker build docker/ -t ghcr.io/dodona-edu/dolos-cli:${{ steps.parse_tag.outputs.version }}
docker build web/ -t ghcr.io/dodona-edu/dolos-web:${{ steps.parse_tag.outputs.version }}
docker build api/ -t ghcr.io/dodona-edu/dolos-api:${{ steps.parse_tag.outputs.version }}
- name: Login to the container registry
run: echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io -u $GITHUB_ACTOR --password-stdin
- name: Tag the new images with latest
run: |
docker tag ghcr.io/dodona-edu/dolos-cli:${{ steps.parse_tag.outputs.version }} ghcr.io/dodona-edu/dolos-cli:latest
docker tag ghcr.io/dodona-edu/dolos-web:${{ steps.parse_tag.outputs.version }} ghcr.io/dodona-edu/dolos-web:latest
docker tag ghcr.io/dodona-edu/dolos-api:${{ steps.parse_tag.outputs.version }} ghcr.io/dodona-edu/dolos-api:latest
- name: Push the images
run: |
docker push --all-tags ghcr.io/dodona-edu/dolos-cli
docker push --all-tags ghcr.io/dodona-edu/dolos-web
docker push --all-tags ghcr.io/dodona-edu/dolos-api