Skip to content

Commit 9f7bfe9

Browse files
feat: scaffold code-quality-scan-workshop with 10 labs, screenshot automation, and Jekyll site
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
0 parents  commit 9f7bfe9

38 files changed

Lines changed: 4135 additions & 0 deletions

File tree

.devcontainer/devcontainer.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"name": "Code Quality Scan Workshop",
3+
"image": "mcr.microsoft.com/devcontainers/universal:2",
4+
"features": {
5+
"ghcr.io/devcontainers/features/docker-in-docker:2": {},
6+
"ghcr.io/devcontainers/features/node:1": { "version": "20" },
7+
"ghcr.io/devcontainers/features/python:1": { "version": "3.12" },
8+
"ghcr.io/devcontainers/features/dotnet:2": { "version": "8.0" },
9+
"ghcr.io/devcontainers/features/java:1": { "version": "21" },
10+
"ghcr.io/devcontainers/features/go:1": { "version": "1.22" }
11+
},
12+
"postCreateCommand": ".devcontainer/post-create.sh",
13+
"customizations": {
14+
"vscode": {
15+
"extensions": [
16+
"dbaeumer.vscode-eslint",
17+
"ms-python.python",
18+
"ms-dotnettools.csharp",
19+
"golang.go",
20+
"ms-vscode.vscode-typescript-next",
21+
"charliermarsh.ruff",
22+
"redhat.java"
23+
]
24+
}
25+
}
26+
}

.devcontainer/post-create.sh

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#!/bin/bash
2+
set -e
3+
4+
DOMAIN="code-quality"
5+
SCANNER_REPO="code-quality-scan-demo-app"
6+
ORG="devopsabcs-engineering"
7+
8+
echo "=========================================="
9+
echo " Code Quality Scan Workshop — Post-Create"
10+
echo "=========================================="
11+
12+
# -----------------------------------------------
13+
# 1. Fork or clone the scanner demo-app as sibling
14+
# -----------------------------------------------
15+
if [ ! -d "../$SCANNER_REPO" ]; then
16+
echo ""
17+
echo "Setting up companion demo-app repository..."
18+
gh repo fork "$ORG/$SCANNER_REPO" --clone -- "../$SCANNER_REPO" 2>/dev/null || \
19+
git clone "https://github.com/$ORG/$SCANNER_REPO.git" "../$SCANNER_REPO"
20+
echo "Demo-app repository cloned to ../$SCANNER_REPO"
21+
else
22+
echo "Demo-app repository already exists at ../$SCANNER_REPO — skipping."
23+
fi
24+
25+
# -----------------------------------------------
26+
# 2. Install ESLint (global for TypeScript linting)
27+
# -----------------------------------------------
28+
echo ""
29+
echo "Installing ESLint..."
30+
npm install -g eslint@latest 2>/dev/null || true
31+
32+
# -----------------------------------------------
33+
# 3. Install Ruff (Python linter)
34+
# -----------------------------------------------
35+
echo ""
36+
echo "Installing Ruff..."
37+
pip install ruff --quiet 2>/dev/null || true
38+
39+
# -----------------------------------------------
40+
# 4. Install jscpd (code duplication detection)
41+
# -----------------------------------------------
42+
echo ""
43+
echo "Installing jscpd..."
44+
npm install -g jscpd@latest 2>/dev/null || true
45+
46+
# -----------------------------------------------
47+
# 5. Install Lizard (cyclomatic complexity)
48+
# -----------------------------------------------
49+
echo ""
50+
echo "Installing Lizard..."
51+
pip install lizard --quiet 2>/dev/null || true
52+
53+
# -----------------------------------------------
54+
# 6. Install golangci-lint (Go linter)
55+
# -----------------------------------------------
56+
echo ""
57+
echo "Installing golangci-lint..."
58+
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b "$(go env GOPATH)/bin" latest 2>/dev/null || true
59+
60+
# -----------------------------------------------
61+
# 7. Install Playwright for screenshot automation
62+
# -----------------------------------------------
63+
echo ""
64+
echo "Installing Playwright..."
65+
npm install -g playwright 2>/dev/null || true
66+
67+
# -----------------------------------------------
68+
# 8. Install demo-app dependencies (if present)
69+
# -----------------------------------------------
70+
if [ -d "../$SCANNER_REPO/cq-demo-app-001" ]; then
71+
echo ""
72+
echo "Installing dependencies for cq-demo-app-001 (TypeScript)..."
73+
cd "../$SCANNER_REPO/cq-demo-app-001" && npm install 2>/dev/null || true
74+
cd -
75+
fi
76+
77+
if [ -d "../$SCANNER_REPO/cq-demo-app-002" ]; then
78+
echo ""
79+
echo "Installing dependencies for cq-demo-app-002 (Python)..."
80+
cd "../$SCANNER_REPO/cq-demo-app-002" && pip install -r requirements.txt --quiet 2>/dev/null || true
81+
cd -
82+
fi
83+
84+
echo ""
85+
echo "=========================================="
86+
echo " Setup complete! Start with Lab 00."
87+
echo "=========================================="

.gitignore

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
node_modules/
2+
_site/
3+
.jekyll-cache/
4+
.jekyll-metadata
5+
Gemfile.lock
6+
*.pyc
7+
__pycache__/
8+
.env
9+
.env.local
10+
*.log
11+
.DS_Store
12+
Thumbs.db
13+
.sass-cache/
14+
.bundle/
15+
vendor/

CONTRIBUTING.md

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
# Contributing to the Code Quality Scan Workshop
2+
3+
Thank you for your interest in improving this workshop! This guide explains how to contribute lab content, screenshots, and fixes.
4+
5+
## Getting Started
6+
7+
1. Fork this repository.
8+
2. Clone your fork locally.
9+
3. Create a feature branch: `git checkout -b feature/your-change`.
10+
4. Make your changes following the standards below.
11+
5. Submit a pull request against `main`.
12+
13+
## Lab Content Standards
14+
15+
### File Structure
16+
17+
Each lab is a directory under `labs/` with a single `README.md`:
18+
19+
```
20+
labs/lab-NN-slug/
21+
└── README.md
22+
```
23+
24+
### Frontmatter
25+
26+
Every lab README MUST include YAML frontmatter:
27+
28+
```yaml
29+
---
30+
permalink: /labs/lab-NN-slug/
31+
title: "Lab NN: Title"
32+
description: "One-sentence description"
33+
---
34+
```
35+
36+
### Required Sections
37+
38+
Every lab README MUST include these sections in order:
39+
40+
1. **Title** (`# Lab NN: Title`)
41+
2. **Metadata table** (Duration, Level, Prerequisites)
42+
3. **Learning Objectives** (3–5 bullets)
43+
4. **Prerequisites** (tools, prior labs)
44+
5. **Exercises** (numbered steps with commands and screenshots)
45+
6. **Verification Checkpoint** (checklist)
46+
7. **Summary** (key takeaways)
47+
8. **Next Steps** (link to next lab)
48+
49+
### Commands
50+
51+
- Use **PowerShell Core** syntax for all commands.
52+
- Wrap commands in fenced code blocks with `powershell` language tag.
53+
- Never use Unix-only commands (`head`, `tail`, `cat`, `2>/dev/null`).
54+
55+
### Working Directory Callouts
56+
57+
When a step requires running commands in the demo-app repository, include:
58+
59+
```markdown
60+
> **Working Directory**: Run the following commands from the `code-quality-scan-demo-app` repository root.
61+
```
62+
63+
## Screenshot Standards
64+
65+
### Naming Convention
66+
67+
```
68+
lab-NN-description-slug.png
69+
```
70+
71+
Examples:
72+
- `lab-02-eslint-output.png`
73+
- `lab-06-security-tab-results.png`
74+
75+
### Screenshot References
76+
77+
Place screenshot references after the step that produces visible output:
78+
79+
```markdown
80+
![ESLint results showing 12 warnings](../images/lab-02/lab-02-eslint-output.png)
81+
```
82+
83+
### Adding New Screenshots
84+
85+
1. Add an entry to `scripts/screenshot-manifest.json`.
86+
2. Run `scripts/capture-screenshots.ps1` to generate the screenshot.
87+
3. Place the generated PNG in the appropriate `images/lab-NN/` directory.
88+
4. Update the `images/lab-NN/README.md` inventory.
89+
90+
### Image Directory README
91+
92+
Each `images/lab-NN/` directory has a `README.md` listing all screenshots:
93+
94+
```markdown
95+
# Lab NN Screenshots
96+
97+
| File | Description |
98+
|------|-------------|
99+
| `lab-NN-slug.png` | Description of what the screenshot shows |
100+
```
101+
102+
## Delivery Guides
103+
104+
The `delivery/` directory contains facilitator guides:
105+
106+
- `half-day.md` — 3.5-hour delivery guide (Labs 00–05 + Lab 06)
107+
- `full-day.md` — 7-hour delivery guide (all labs)
108+
109+
When adding labs, update both delivery guides with timing adjustments.
110+
111+
## Pull Request Process
112+
113+
1. Ensure your changes render correctly with Jekyll locally (`bundle exec jekyll serve`).
114+
2. Verify all screenshot references resolve to existing files.
115+
3. Test any commands in a GitHub Codespace.
116+
4. Update the screenshot manifest if adding new screenshots.
117+
5. Submit a PR with a clear description of changes.
118+
119+
## Code of Conduct
120+
121+
Be respectful, constructive, and inclusive. We follow the [Contributor Covenant](https://www.contributor-covenant.org/) Code of Conduct.

Gemfile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
source "https://rubygems.org"
2+
gem "github-pages", group: :jekyll_plugins
3+
gem "webrick", "~> 1.8"

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 devopsabcs-engineering
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Code Quality Scan Workshop
2+
3+
[![GitHub Pages](https://img.shields.io/badge/docs-GitHub%20Pages-blue)](https://devopsabcs-engineering.github.io/code-quality-scan-workshop/)
4+
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
5+
6+
Hands-on workshop for code quality scanning with ESLint, Ruff, jscpd, Lizard, and coverage tools. Learn to integrate a **4-tool scanning architecture** into your CI/CD pipelines and visualize results in GitHub Advanced Security, Azure DevOps Advanced Security, and Power BI.
7+
8+
## Quick Start
9+
10+
### Option 1: GitHub Codespaces (Recommended)
11+
12+
1. Click **Code → Codespaces → New codespace** on this repository.
13+
2. Wait for the dev container to build (~3 minutes).
14+
3. Open the terminal and start with [Lab 00](labs/lab-00-prerequisites/).
15+
16+
### Option 2: Local Setup
17+
18+
1. Clone this repository:
19+
20+
```powershell
21+
git clone https://github.com/devopsabcs-engineering/code-quality-scan-workshop.git
22+
cd code-quality-scan-workshop
23+
```
24+
25+
2. Clone the companion demo-app repository as a sibling:
26+
27+
```powershell
28+
git clone https://github.com/devopsabcs-engineering/code-quality-scan-demo-app.git
29+
```
30+
31+
3. Install prerequisites from [Lab 00](labs/lab-00-prerequisites/).
32+
33+
## Labs
34+
35+
| # | Lab | Duration | Level |
36+
|---|-----|----------|-------|
37+
| 00 | [Prerequisites](labs/lab-00-prerequisites/) | 30 min | Beginner |
38+
| 01 | [Explore Demo Apps](labs/lab-01-explore-demo-apps/) | 30 min | Beginner |
39+
| 02 | [Linting](labs/lab-02-linting/) | 45 min | Intermediate |
40+
| 03 | [Complexity Analysis](labs/lab-03-complexity/) | 30 min | Intermediate |
41+
| 04 | [Duplication Detection](labs/lab-04-duplication/) | 30 min | Intermediate |
42+
| 05 | [Coverage Analysis](labs/lab-05-coverage/) | 45 min | Intermediate |
43+
| 06 | [GitHub Actions CI/CD](labs/lab-06-github-actions/) | 30 min | Intermediate |
44+
| 06-ADO | [ADO Pipelines CI/CD](labs/lab-06-ado-pipelines/) | 30 min | Intermediate |
45+
| 07 | [Remediation (GitHub)](labs/lab-07-remediation-github/) | 45 min | Advanced |
46+
| 07-ADO | [Remediation (ADO)](labs/lab-07-ado-remediation/) | 45 min | Advanced |
47+
| 08 | [Power BI Dashboard](labs/lab-08-dashboard/) | 45 min | Advanced |
48+
49+
## Scanning Architecture
50+
51+
The workshop teaches a **4-tool architecture** for comprehensive code quality scanning:
52+
53+
| Tool | Role | Output |
54+
|------|------|--------|
55+
| Per-language linters (ESLint, Ruff, .NET Analyzers, Checkstyle, golangci-lint) | Static analysis | Native SARIF |
56+
| jscpd | Code duplication detection | Native SARIF |
57+
| Lizard | Cyclomatic complexity analysis | CSV → SARIF via `lizard-to-sarif.py` |
58+
| Coverage tools (Jest, pytest-cov, Coverlet, JaCoCo, go test) | Test coverage measurement | Various → SARIF via `coverage-to-sarif.py` |
59+
60+
All results are normalized to **SARIF v2.1.0** and uploaded to GitHub Security tab or ADO Advanced Security for unified triage.
61+
62+
## Companion Repository
63+
64+
This workshop uses the [code-quality-scan-demo-app](https://github.com/devopsabcs-engineering/code-quality-scan-demo-app) repository, which contains:
65+
66+
- 5 demo applications (TypeScript, Python, C#, Java, Go) with intentional quality violations
67+
- SARIF converter scripts for Lizard and coverage tools
68+
- CI/CD pipelines for GitHub Actions and Azure DevOps
69+
- Power BI PBIP report for quality dashboards
70+
71+
## Prerequisites Summary
72+
73+
- Node.js 20+ · Python 3.12+ · .NET 8 SDK · Java 21+ · Go 1.22+
74+
- Docker Desktop (or Codespaces with Docker-in-Docker)
75+
- Visual Studio Code with ESLint, Python, C#, and Go extensions
76+
- GitHub CLI (`gh`) authenticated
77+
78+
## Contributing
79+
80+
See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines on adding labs, screenshots, and fixes.
81+
82+
## License
83+
84+
This project is licensed under the MIT License — see [LICENSE](LICENSE) for details.

_config.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
title: "Code Quality Scan Workshop"
2+
description: "Hands-on workshop: Code quality scanning with ESLint, Ruff, jscpd, Lizard, and coverage tools"
3+
remote_theme: just-the-docs/just-the-docs
4+
baseurl: "/code-quality-scan-workshop"
5+
url: "https://devopsabcs-engineering.github.io"
6+
7+
exclude:
8+
- scripts/
9+
- delivery/
10+
- .devcontainer/
11+
- node_modules/
12+
- package.json
13+
- package-lock.json
14+
- Gemfile.lock
15+
16+
nav_order_base: 0
17+
heading_anchors: true

_includes/head-custom.html

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<script type="module">
2+
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
3+
mermaid.initialize({ startOnLoad: true });
4+
document.querySelectorAll('pre > code.language-mermaid').forEach(el => {
5+
const div = document.createElement('div');
6+
div.className = 'mermaid';
7+
div.textContent = el.textContent;
8+
el.parentElement.replaceWith(div);
9+
});
10+
</script>
11+
<style>
12+
.mermaid { text-align: center; }
13+
</style>

0 commit comments

Comments
 (0)