Skip to content

Basic CI Checks #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Mar 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .copier-answers.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Changes here will be overwritten by Copier
_commit: v0.0.10
_commit: v0.0.12
_src_path: gh:LabAutomationAndScreening/copier-base-template.git
description: A web app that is hosted within a local intranet. Nuxt frontend, python
backend, docker-compose
Expand Down
5 changes: 5 additions & 0 deletions .devcontainer/install-ci-tooling.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
# can pass in the full major.minor.patch version of python as an optional argument
set -ex


npm -v
npm install -g [email protected]
pnpm -v

curl -LsSf https://astral.sh/uv/0.6.6/install.sh | sh
uv --version
# TODO: add uv autocompletion to the shell https://docs.astral.sh/uv/getting-started/installation/#shell-autocompletion
Expand Down
2 changes: 1 addition & 1 deletion .github/actions/install_deps_uv/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ runs:

- name: OIDC Auth for CodeArtifact
if: ${{ inputs.code-artifact-auth-role-name != 'no-code-artifact' }}
uses: aws-actions/configure-aws-credentials@v4.0.2
uses: aws-actions/configure-aws-credentials@v4.1.0
with:
role-to-assume: arn:aws:iam::${{ inputs.code-artifact-auth-role-account-id }}:role/${{ inputs.code-artifact-auth-role-name }}
aws-region: ${{ inputs.code-artifact-auth-region }}
Expand Down
11 changes: 9 additions & 2 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,19 @@ jobs:
- "ubuntu-24.04"
python-version:
- 3.12.7
node-version:
- 22.14.0
name: Pre-commit for Py${{ matrix.python-version }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
steps:
- name: Checkout code
uses: actions/[email protected]

- name: Setup node
uses: actions/[email protected]
with:
node-version: ${{ matrix.node-version }}

- name: Install latest versions of python packages
uses: ./.github/actions/install_deps_uv
with:
Expand All @@ -42,7 +49,7 @@ jobs:
timeout-minutes: 30 # this is the amount of time this action will wait to attempt to acquire the mutex lock before failing, e.g. if other jobs are queued up in front of it

- name: Cache Pre-commit hooks
uses: actions/[email protected].0
uses: actions/[email protected].2
env:
cache-name: cache-pre-commit-hooks
with:
Expand Down Expand Up @@ -129,7 +136,7 @@ jobs:
timeout-minutes: 30 # this is the amount of time this action will wait to attempt to acquire the mutex lock before failing, e.g. if other jobs are queued up in front of it

- name: Cache Pre-commit hooks
uses: actions/[email protected].0
uses: actions/[email protected].2
env:
cache-name: cache-pre-commit-hooks
with:
Expand Down
18 changes: 10 additions & 8 deletions extensions/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class ContextUpdater(ContextHook):
@override
def hook(self, context: dict[Any, Any]) -> dict[Any, Any]:
context["uv_version"] = "0.6.6"
context["pnpm_version"] = "10.6.3"
context["pre_commit_version"] = "4.1.0"
context["pyright_version"] = "1.1.396"
context["pytest_version"] = "8.3.4"
Expand All @@ -19,22 +20,23 @@ def hook(self, context: dict[Any, Any]) -> dict[Any, Any]:
context["copier_version"] = "9.5.0"
context["copier_templates_extension_version"] = "0.3.0"
context["sphinx_version"] = "8.1.3"
context["pulumi_version"] = "3.155.0"
context["pulumi_aws_version"] = "6.67.0"
context["pulumi_aws_native_version"] = "1.25.0"
context["pulumi_command_version"] = "1.0.1"
context["pulumi_version"] = "3.156.0"
context["pulumi_aws_version"] = "6.72.0"
context["pulumi_aws_native_version"] = "1.26.0"
context["pulumi_command_version"] = "1.0.2"
context["pulumi_github"] = ""
context["boto3_version"] = "1.37.11"
context["ephemeral_pulumi_deploy_version"] = "0.0.2"
context["ephemeral_pulumi_deploy_version"] = "0.0.4"
context["pydantic_version"] = "2.10.6"
context["pyinstaller_version"] = "6.12.0"
context["setuptools_version"] = "76.0.0"

context["gha_checkout"] = "v4.2.2"
context["gha_setup_python"] = "v5.4.0"
context["gha_cache"] = "v4.2.0"
context["gha_upload_artifact"] = "v4.4.3"
context["gha_configure_aws_credentials"] = "v4.0.2"
context["gha_cache"] = "v4.2.2"
context["gha_upload_artifact"] = "v4.6.1"
context["gha_configure_aws_credentials"] = "v4.1.0"
context["gha_setup_node"] = "v4.3.0"
context["gha_mutex"] = "1ebad517141198e08d47cf72f3c0975316620a65 # v1.0.0-alpha.10"
context["gha_linux_runner"] = "ubuntu-24.04"
context["gha_windows_runner"] = "windows-2022"
Expand Down
5 changes: 5 additions & 0 deletions template/.devcontainer/install-ci-tooling.sh.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
# can pass in the full major.minor.patch version of python as an optional argument
set -ex

{% endraw %}{% if template_uses_javascript is defined and template_uses_javascript is sameas(true) %}{% raw %}
npm -v
npm install -g pnpm@{% endraw %}{{ pnpm_version }}{% raw %}
pnpm -v{% endraw %}{% endif %}{% raw %}

curl -LsSf https://astral.sh/uv/{% endraw %}{{ uv_version }}{% raw %}/install.sh | sh
uv --version
# TODO: add uv autocompletion to the shell https://docs.astral.sh/uv/getting-started/installation/#shell-autocompletion
Expand Down
15 changes: 9 additions & 6 deletions template/.devcontainer/manual-setup-deps.sh.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ export UV_PYTHON="$python_version"
export UV_PYTHON_PREFERENCE=only-system

SCRIPT_DIR="$(dirname "$0")"
PROJECT_ROOT_DIR="$(realpath "$SCRIPT_DIR/../backend")"

PROJECT_ROOT_DIR="$(realpath "$SCRIPT_DIR/..")"
PYTHON_PROJECT_DIR="$PROJECT_ROOT_DIR/backend"
# If optionally_lock is set, decide whether to skip locking based on the presence of uv.lock
if [ "$optionally_lock" = "true" ]; then
if [ ! -f "$PROJECT_ROOT_DIR/uv.lock" ]; then
if [ ! -f "$PYTHON_PROJECT_DIR/uv.lock" ]; then
skip_lock=true
else
skip_lock=false
Expand All @@ -46,8 +46,11 @@ fi

# Ensure that the lock file is in a good state
if [ "$skip_lock" = "false" ]; then
uv lock --check --directory "$PROJECT_ROOT_DIR"
uv lock --check --directory "$PYTHON_PROJECT_DIR"
fi

uv sync $( [ "$skip_lock" = "false" ] && echo "--frozen" ) --directory "$PROJECT_ROOT_DIR"
uv pip list --directory "$PROJECT_ROOT_DIR"{% endraw %}
uv sync $( [ "$skip_lock" = "false" ] && echo "--frozen" ) --directory "$PYTHON_PROJECT_DIR"
uv pip list --directory "$PYTHON_PROJECT_DIR"

NPM_PROJECT_DIR="$PROJECT_ROOT_DIR/frontend"
pnpm install --dir="$NPM_PROJECT_DIR"{% endraw %}
2 changes: 1 addition & 1 deletion template/.github/actions/install_deps_uv/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ runs:

- name: OIDC Auth for CodeArtifact
if: ${{ inputs.code-artifact-auth-role-name != 'no-code-artifact' }}
uses: aws-actions/configure-aws-credentials@v4.0.2
uses: aws-actions/configure-aws-credentials@v4.1.0
with:
role-to-assume: arn:aws:iam::${{ inputs.code-artifact-auth-role-account-id }}:role/${{ inputs.code-artifact-auth-role-name }}
aws-region: ${{ inputs.code-artifact-auth-region }}
Expand Down
63 changes: 63 additions & 0 deletions template/.github/workflows/ci.yaml.jinja
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
{% raw %}name: CI

on:
push:
branches-ignore:
- 'gh-readonly-queue/**' # don't run (again) when on these special branches created during merge groups; the `on: merge_group` already triggers it.
merge_group:

env:
PYTHONUNBUFFERED: True
PRE_COMMIT_HOME: ${{ github.workspace }}/.precommit_cache

permissions:
id-token: write
contents: write # needed for mutex

jobs:
lint:
name: Pre-commit
runs-on: {% endraw %}{{ gha_linux_runner }}{% raw %}
steps:
- name: Checkout code
uses: actions/checkout@{% endraw %}{{ gha_checkout }}{% raw %}

- name: Setup node
uses: actions/setup-node@{% endraw %}{{ gha_setup_node }}{% raw %}
with:
node-version: {% endraw %}{{ node_version }}{% raw %}

- name: Install latest versions of python packages
uses: ./.github/actions/install_deps_uv
with:
python-version: {% endraw %}{{ python_version }}{% raw %}

- name: Set up mutex # Github concurrency management is horrible, things get arbitrarily cancelled if queued up. So using mutex until github fixes itself. When multiple jobs are modifying cache at once, weird things can happen. possible issue is https://github.com/actions/toolkit/issues/658
if: ${{ runner.os != 'Windows' }} # we're just gonna have to YOLO on Windows, because this action doesn't support it yet https://github.com/ben-z/gh-action-mutex/issues/14
uses: ben-z/gh-action-mutex@{% endraw %}{{ gha_mutex }}{% raw %}
with:
branch: mutex-venv-{% endraw %}{{ gha_linux_runner }}{% raw %}-py{% endraw %}{{ python_version }}{% raw %}
timeout-minutes: 30 # this is the amount of time this action will wait to attempt to acquire the mutex lock before failing, e.g. if other jobs are queued up in front of it

- name: Cache Pre-commit hooks
uses: actions/cache@{% endraw %}{{ gha_cache }}{% raw %}
env:
cache-name: cache-pre-commit-hooks
with:
path: ${{ env.PRE_COMMIT_HOME }}
key: {% endraw %}{{ gha_linux_runner }}{% raw %}-py{% endraw %}{{ python_version }}{% raw %}-build-${{ env.cache-name }}-${{ hashFiles('.pre-commit-config.yaml') }}
restore-keys: |
{% endraw %}{{ gha_linux_runner }}{% raw %}-py{% endraw %}{{ python_version }}{% raw %}-build-${{ env.cache-name }}-

- name: Run pre-commit
run: pre-commit run -a

required-check:
runs-on: {% endraw %}{{ gha_linux_runner }}{% raw %}
needs: [ lint ]
if: always()
steps:
- name: fail if prior job failure
if: needs.lint.result != 'success'
run: |
exit 1{% endraw %}
28 changes: 28 additions & 0 deletions template/.pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,34 @@ repos:

# Linting

- repo: local
hooks:
- id: typescript-check
name: typescript-check
entry: bash -c "pnpm --dir frontend run type-check"
files: '.+\.ts$|.+\.vue$'
# don't pass filenames else the command line sees them twice
pass_filenames: false
language: system
# use require_serial so that script is only called once per commit
require_serial: true
# print the number of files as a sanity-check
verbose: true

- repo: local
hooks:
- id: eslint
name: eslint
entry: bash -c "pnpm --dir frontend run lint"
files: '.+\.ts$|.+\.vue$|.+\.js$'
# don't pass filenames else the command line sees them twice
pass_filenames: false
language: system
# use require_serial so that script is only called once per commit
require_serial: true
# print the number of files as a sanity-check
verbose: true

- repo: https://github.com/Lucas-C/pre-commit-hooks-markup
rev: 501f3d60cee13c712492103343bc23efdc7b3d1f #v1.0.1
hooks:
Expand Down
11 changes: 11 additions & 0 deletions template/frontend/app.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export default defineAppConfig({
ui: {
primary: "sky",
gray: "cool",
tooltip: {
default: {
openDelay: 500,
},
},
},
});
2 changes: 2 additions & 0 deletions template/frontend/assets/css/main.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@import "tailwindcss" theme(static);
@import "@nuxt/ui";
34 changes: 34 additions & 0 deletions template/frontend/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import withNuxt from "./.nuxt/eslint.config.mjs";

export default withNuxt(
{
// Disallow <script lang="js"> in Vue files
files: ["**/*.vue"],
rules: {
"vue/block-lang": [
"error",
{
script: {
lang: "ts",
},
},
],
},
},
{
// Disallow .js files in your source
files: ["**/*.js"],
ignores: [
// add exceptions here if you must allow certain .js files
],
rules: {
"no-restricted-syntax": [
"error",
{
selector: "Program",
message: "Use .ts instead of .js.",
},
],
},
},
);
7 changes: 7 additions & 0 deletions template/frontend/global.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/// <reference types="nuxt/app" />
// needed to help avoid typescript error in app.config.ts
declare global {
const defineAppConfig: typeof import("nuxt/app").defineAppConfig;
}

export {};
5 changes: 5 additions & 0 deletions template/frontend/layouts/default.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<template>
<UApp>
<NuxtPage />
</UApp>
</template>
2 changes: 2 additions & 0 deletions template/frontend/nuxt.config.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
// https://nuxt.com/docs/api/configuration/nuxt-config
import { defineNuxtConfig } from "nuxt/config";
export default defineNuxtConfig({
compatibilityDate: "2024-11-01",
devtools: { enabled: true },
modules: ["@nuxt/eslint", "@nuxt/test-utils", "@nuxt/ui"],
css: ["~/assets/css/main.css"],
experimental: { appManifest: false }, // https://github.com/nuxt/nuxt/issues/30461#issuecomment-2572616714
vite: {
// this seems to be explicitly needed when in a devcontainer in order for hot reloading to work
Expand Down
33 changes: 33 additions & 0 deletions template/frontend/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "nuxt-app",
"private": true,
"type": "module",
"scripts": {
"type-check": "vue-tsc --noEmit",
"lint": "eslint . --ext .vue,.ts,.js",
"build": "pnpm run type-check && nuxt build",
"dev": "nuxt dev",
"generate": "nuxt generate",
"preview": "nuxt preview",
"postinstall": "nuxt prepare"
},
"dependencies": {
"@nuxt/ui": "3.0.0",
"nuxt": "^3.16.0",
"typescript": "^5.8.2",
"vue": "^3.5.13",
"vue-router": "^4.5.0"
},
"devDependencies": {
"@nuxt/eslint": "^1.2.0",
"@nuxt/test-utils": "^3.17.2",
"@nuxtjs/eslint-config-typescript": "^12.1.0",
"autoprefixer": "^10.4.21",
"eslint": "^9.22.0",
"postcss": "^8.5.3",
"tailwindcss": "^4.0.14",
"vue-eslint-parser": "^10.1.1",
"vue-tsc": "^2.2.8",
"@nuxt/schema": "^3.0.0"
}
}
3 changes: 3 additions & 0 deletions template/frontend/pages/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<template>
<div>Hello World!</div>
</template>
14 changes: 14 additions & 0 deletions template/frontend/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
// https://nuxt.com/docs/guide/concepts/typescript
"extends": "./.nuxt/tsconfig.json",
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"strict": true,
"moduleResolution": "node",
"esModuleInterop": true,
"skipLibCheck": true
},
"include": ["global.d.ts", "types/**/*.d.ts", "nuxt.config.ts", "app.config.ts"],
"exclude": ["node_modules", ".output", ".nuxt", "dist"]
}