Freelance landing page built with Angular 22, deployed on GitHub Pages.
π Live site: https://alderichoarau.github.io (mirrored on GitLab Pages β bonus backup copy, GitHub Pages is the real deployment)
CI
Deploy
GitHub is the source of truth. This repository is automatically push-mirrored (read-only) to:
Issues and pull requests should be opened on GitHub.
| Category | Technology |
|---|---|
| Framework | Angular 22 β Standalone Components, Signals |
| UI | Angular Material 22 with custom dark theme |
| i18n | ngx-translate (FR / EN) |
| Testing | Vitest + @analogjs/vitest-angular + jsdom |
| Coverage | @vitest/coverage-v8 (lcov β SonarCloud) |
| Build | Angular CLI / esbuild |
| Quality | ESLint + Prettier + Husky pre-commit |
| CI/CD | GitHub Actions |
| Analysis | SonarCloud |
| Section | Description |
|---|---|
| Hero | Introduction, key stats, CTAs, social links |
| Technologies | Stack by category (Frontend, Backend, Cloud, etc.) |
| Experience | Timeline from 2015 to present |
| Credentials | Microsoft/Scrum certifications + languages |
| References | Client logos (infinite scroll carousel) |
| FAQ | 7 frequently asked questions about services |
| Contact | Email, LinkedIn, Malt, GitHub, Collective |
Requirements: Node.js 26+, npm 11+
git clone https://github.com/alderichoarau/alderichoarau.github.io.git
cd alderichoarau.github.io
npm install
npm start
# β http://localhost:4200# Development
npm start # Development server
npm run build # Standard build
npm run build:prod # Production build
# Code quality
npm run lint # ESLint check
npm run lint:fix # ESLint with auto-fix
npm run format # Prettier (write)
npm run format:check # Prettier (check only)
npm run check # lint + format:check
# Testing
npm run test # Single run (Vitest)
npm run test:watch # Watch mode
npm run test:coverage # Tests + lcov coverage reportsrc/
βββ app/
β βββ core/
β β βββ components/ # Navigation, Footer
β β βββ services/ # DataService, ScrollAnimationService,
β β # SeoService, TranslationService
β βββ features/
β β βββ about/ # Hero section
β β βββ technologies/ # Tech stack
β β βββ experience/ # Timeline
β β βββ certifications/ # Certifications + languages
β β βββ references/ # Client logos
β β βββ faq/ # FAQ accordion
β β βββ contact/ # Contact
βββ assets/
β βββ i18n/ # fr.json, en.json
βββ test-setup.ts # Vitest setup (zone.js + TestBed)
βββ styles.scss # Global theme + CSS variables
Tests run with Vitest + @analogjs/vitest-angular (jsdom β no browser required).
npm run test # 151 tests, ~3s
npm run test:coverage # Generates coverage/lcov.infoCoverage target: 80% statements / functions / lines.
| File | Trigger | Role |
|---|---|---|
ci.yml |
PR + push to main + manual |
Lint β Format check β Test β Build |
a11y.yml |
PR + push to main + manual |
Accessibility audit (axe-core) β PR/push job audits this branch's build, manual dispatch audits the live site |
sca.yml |
PR + push to main + manual |
Dependency vulnerability scan (Trivy) |
secrets-scan.yml |
PR + push to main + manual |
Leaked secret scan (gitleaks) |
dast.yml |
Manual (workflow_dispatch) |
OWASP ZAP baseline scan against the real deployed site |
sonar.yml |
Push to main + PR + manual |
Generate coverage β SonarCloud analysis (SAST) |
| CodeQL | GitHub default setup (weekly) | SAST, no workflow file β configured under repo Settings β Code security |
dependency-review.yml |
Pull Request | Audit new dependencies |
deploy.yml |
Manual (workflow_dispatch) |
Lint β Test β Build β Deploy to GitHub Pages |
release-prepare.yml |
Manual (workflow_dispatch) |
Bump version, open the release PR |
release-publish.yml |
Release PR merged | Create the git tag + GitHub release |
sca.yml/secrets-scan.yml/dast.yml/a11y.yml used to be jobs inside ci.yml (a11y, security) β split into their own files for a named badge/check per category, same convention as azure-quiz-frontend/azure-quiz-backend. No Container/IaC scan here: this repo has no Dockerfile/Helm/Terraform, nothing for that category to check.
Triggered manually via workflow_dispatch, or dispatched by release-publish.yml right after it creates a release, via gh workflow run deploy.yml --ref <tag> (a release created with GITHUB_TOKEN doesn't emit an event other workflows can react to, so a release: published trigger wouldn't fire here). Deploys the exact commit pointed to by the release's tag.
- Checkout code
npm run lintβ ESLint checknpm run testβ Vitest suitenpm run buildβ Angular build (esbuild)- Upload
docs/browser/β GitHub Pages
- Checkout code
npm run test:coverageβ generatescoverage/lcov.info- SonarCloud scan using the lcov report
Sonar configuration is in sonar-project.properties.
main is a protected branch, so the release is a two-step process:
- Prepare β manually trigger
release-prepare.ymlfrom the Actions tab with atag_nameinput (e.g.v2.1.0). It bumpspackage.json/package-lock.json, pushes arelease/<tag_name>branch, and opens a PR intomain. - Publish β once that PR is reviewed and merged,
release-publish.ymlfires automatically: it creates and pushes the<tag_name>tag on the merge commit, then creates the matching GitHub release with auto-generated notes.
Publishing the release automatically triggers deploy.yml, so merging the release PR is the standard way to ship to production.
- ESLint + angular-eslint for TypeScript and templates
- Prettier for consistent formatting
- Husky pre-commit hook (lint-staged)
- SonarCloud for continuous static analysis
Β© 2026 AldΓ©ric Hoarau. All rights reserved. This repository is public for viewing purposes only β see LICENSE. External contributions are not accepted, see CONTRIBUTING.md.
AldΓ©ric Hoarau β Cloud Consultant & DevOps Trainer