Skip to content
Draft
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
98 changes: 92 additions & 6 deletions .github/actions/build-node-python/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ inputs:
run_python_build:
default: true
required: false
auto_fix_lint:
description: "automatically fix linting errors when possible and commit changes"
default: false
required: false

runs:
using: "composite"
Expand Down Expand Up @@ -161,6 +165,33 @@ runs:
run: |
# Run node and python in parallel

# Function to setup git for committing fixes
setup_git_for_fixes() {
git config --global user.name "github-actions[bot]"
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
}

# Function to commit lint fixes
commit_lint_fixes() {
local changes_made="$1"
if [ "$changes_made" = "true" ]; then
if git diff --quiet && git diff --cached --quiet; then
echo "No changes to commit after running fixes"
return 0
fi

echo "Committing lint fixes..."
git add .
if git diff --cached --quiet; then
echo "No staged changes to commit"
return 0
fi
git commit -m "Auto-fix: Apply linting and formatting fixes" || true
git push || true
echo "βœ“ Lint fixes committed and pushed"
fi
}

# Define the node sequence of commands
node_job() {
set -e
Expand All @@ -172,10 +203,34 @@ runs:
}
done

parallel_jobs=()
# Handle node linting with auto-fix capability
if [ "$RUN_NODE_LINT" = "true" ]; then
parallel_jobs+=("yarn run lint --quiet")
echo "Running node lint..."
if ! yarn run lint --quiet; then
if [ "$AUTO_FIX_LINT" = "true" ]; then
echo "Node lint failed. Attempting to auto-fix..."
setup_git_for_fixes
yarn run lint:fix || echo "Warning: yarn lint:fix command failed or not available"

echo "Re-running node lint after fixes..."
if yarn run lint --quiet; then
echo "βœ“ Node lint passed after auto-fix"
commit_lint_fixes "true"
else
echo "βœ— Node lint still failing after auto-fix"
exit 1
fi
else
echo "βœ— Node lint failed and auto-fix is disabled"
exit 1
fi
else
echo "βœ“ Node lint passed"
fi
fi

# Run other node tasks
parallel_jobs=()
if [ "$RUN_NODE_TEST" = "true" ]; then
parallel_jobs+=("yarn run test")
fi
Expand All @@ -189,31 +244,61 @@ runs:
parallel_jobs+=("yarn playwright install --with-deps chromium")
fi

parallel --jobs $1 --lb --halt-on-error 2 --verbose ::: "${parallel_jobs[@]}"
if [ ${#parallel_jobs[@]} -gt 0 ]; then
parallel --jobs $1 --lb --halt-on-error 2 --verbose ::: "${parallel_jobs[@]}"
fi
}

# Define the python sequence of commands
python_job() {
set -e
make develop

parallel_jobs=()
# Handle python linting with auto-fix capability
if [ "$RUN_PYTHON_LINT" = "true" ]; then
parallel_jobs+=("make lint check-format")
echo "Running python lint..."
if ! make lint check-format; then
if [ "$AUTO_FIX_LINT" = "true" ]; then
echo "Python lint failed. Attempting to auto-fix..."
setup_git_for_fixes
make format || echo "Warning: make format command failed or not available"

echo "Re-running python lint after fixes..."
if make lint check-format; then
echo "βœ“ Python lint passed after auto-fix"
commit_lint_fixes "true"
else
echo "βœ— Python lint still failing after auto-fix"
exit 1
fi
else
echo "βœ— Python lint failed and auto-fix is disabled"
exit 1
fi
else
echo "βœ“ Python lint passed"
fi
fi

# Run other python tasks
parallel_jobs=()
if [ "$RUN_PYTHON_TEST" = "true" ]; then
parallel_jobs+=("make test")
fi
if [ "$RUN_PYTHON_BUILD" = "true" ]; then
parallel_jobs+=("make build")
fi

parallel --jobs $1 --lb --halt-on-error 2 --verbose ::: "${parallel_jobs[@]}"
if [ ${#parallel_jobs[@]} -gt 0 ]; then
parallel --jobs $1 --lb --halt-on-error 2 --verbose ::: "${parallel_jobs[@]}"
fi
}

# Export the functions so they can be used by GNU parallel
export -f node_job
export -f python_job
export -f setup_git_for_fixes
export -f commit_lint_fixes

# If RUN_PARALLEL is set, set --jobs to 0, otherwise to 1
N_JOBS=1
Expand Down Expand Up @@ -243,6 +328,7 @@ runs:
RUN_PYTHON_LINT: ${{ inputs.run_python_lint }}
RUN_PYTHON_TEST: ${{ inputs.run_python_test }}
RUN_PYTHON_BUILD: ${{ inputs.run_python_build }}
AUTO_FIX_LINT: ${{ inputs.auto_fix_lint }}
# Node
- name: Save yarn cache
uses: actions/cache/save@v4
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/build-node-python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ on:
required: false
# When using github.ref || github.head_ref, it would contain the full path, including /, which breaks the postgres hostname
default: ${{ github.sha }}
auto_fix_lint:
description: "Automatically fix linting errors when possible and commit changes"
type: boolean
required: false
default: false
cypress_enable:
description: "Global enable for cypress"
type: boolean
Expand Down Expand Up @@ -156,6 +161,7 @@ jobs:
enable_python_cache: ${{ inputs.runs_on != 'self-hosted' }}
chromatic_enable: ${{ inputs.chromatic_enable }}
chromatic_project_token: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
auto_fix_lint: ${{ inputs.auto_fix_lint }}

build-python:
name: Python
Expand Down Expand Up @@ -193,6 +199,7 @@ jobs:
run_node_bundle: ${{ inputs.node_run_webpack }}
enable_node_cache: ${{ inputs.runs_on != 'self-hosted' }}
enable_python_cache: ${{ inputs.runs_on != 'self-hosted' }}
auto_fix_lint: ${{ inputs.auto_fix_lint }}

# If cypress is used, build node and python sequentially as it is avoiding the duplicate install overhead
build-node-python-cypress:
Expand Down Expand Up @@ -285,6 +292,7 @@ jobs:
enable_python_cache: ${{ inputs.cypress_runs_on != 'self-hosted' && inputs.runs_on != 'self-hosted' }}
chromatic_enable: ${{ inputs.chromatic_enable }}
chromatic_project_token: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
auto_fix_lint: ${{ inputs.auto_fix_lint }}
- name: Decrypt .env.enc and <app>/.env.enc
run: |
yarn run env:decrypt -pass env:ENV_PASSWORD || true
Expand Down Expand Up @@ -428,6 +436,7 @@ jobs:
enable_python_cache: ${{ inputs.playwright_runs_on != 'self-hosted' && inputs.runs_on != 'self-hosted' }}
chromatic_enable: false # Set to false as we run chromatic below w/ playwright integration
chromatic_project_token: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
auto_fix_lint: ${{ inputs.auto_fix_lint }}
- name: Decrypt .env.enc and <app>/.env.enc
run: |
yarn run env:decrypt -pass env:ENV_PASSWORD || true
Expand Down
49 changes: 49 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,55 @@
# github-workflows
contains github workflows for the datavisyn organisation

## Auto-Fix Linting Functionality

The `build-node-python` action now supports automatic fixing of linting errors. When enabled, the action will:

1. Run the normal linting process first
2. If linting fails and auto-fix is enabled, attempt to fix errors using:
- `yarn lint:fix` for frontend/Node.js projects
- `make format` for backend/Python projects
3. Re-run the linting process to verify fixes worked
4. Commit and push changes if fixes were successful

### Usage

#### Via workflow_call
```yaml
jobs:
build:
uses: datavisyn/github-workflows/.github/workflows/build-node-python.yml@main
with:
auto_fix_lint: true # Enable auto-fix (default: false)
```

#### Via workflow_dispatch
The `build-node-python.yml` workflow can now be manually triggered with:
- `auto_fix_lint`: Enable automatic fixing of linting errors
- Other standard parameters like `run_parallel`, `cypress_enable`, etc.

#### Direct action usage
```yaml
- uses: datavisyn/github-workflows/.github/actions/build-node-python@main
with:
auto_fix_lint: true
# ... other parameters
```

### Requirements

For auto-fix to work, your project should have:
- `yarn lint:fix` command available (for Node.js projects)
- `make format` target available (for Python projects)
- Proper git permissions for the workflow to commit and push changes

### Notes

- Auto-fix is disabled by default to maintain backward compatibility
- Fixed files are committed with message: "Auto-fix: Apply linting and formatting fixes [skip ci]"
- If fixes don't resolve all linting issues, the workflow will still fail
- The workflow requires `contents: write` permission to commit changes

## Linting
We use super-linter from github (see <https://github.com/github/super-linter>)

Expand Down