diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 19288a7..7e5ed9d 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -10,9 +10,32 @@ permissions: id-token: write jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Validate files + run: | + echo "Validating CV website files..." + if [ ! -f "index.html" ]; then + echo "Error: index.html not found!" + exit 1 + fi + echo "✓ index.html found" + if [ ! -f "print.css" ]; then + echo "Warning: print.css not found" + else + echo "✓ print.css found" + fi + echo "✓ Build validation complete" + deploy: + needs: build environment: name: github-pages + url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest steps: - name: Checkout diff --git a/.github/workflows/sync-to-gitlab.yml b/.github/workflows/sync-to-gitlab.yml new file mode 100644 index 0000000..bca5033 --- /dev/null +++ b/.github/workflows/sync-to-gitlab.yml @@ -0,0 +1,42 @@ +name: Sync to GitLab + +on: + push: + branches: + - main + - style-updates + - deployment-development + tags: + - '*' + +jobs: + sync: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Fetch all history for proper syncing + + - name: Configure Git + run: | + git config user.name "GitHub Actions" + git config user.email "actions@github.com" + + - name: Add GitLab remote + run: | + git remote add gitlab git@hill-st.nohost.me:pwflint/CV.git || true + git remote set-url gitlab git@hill-st.nohost.me:pwflint/CV.git + + - name: Setup SSH + uses: webfactory/ssh-agent@v0.9.0 + with: + ssh-private-key: ${{ secrets.GITLAB_SSH_PRIVATE_KEY }} + + - name: Push to GitLab + run: | + git push gitlab ${GITHUB_REF#refs/heads/} || true + # If pushing main, also try to update other branches if they exist + if [ "${GITHUB_REF#refs/heads/}" = "main" ]; then + git push gitlab main || true + fi diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9781ea1..3efda81 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,9 +1,99 @@ +# GitLab CI/CD Pipeline for CV Website Deployment +# NOTE: This repository uses GitHub Pages for deployment via GitHub Actions +# This GitLab CI/CD configuration is provided as an alternative option +# if you want to deploy to GitLab Pages instead +# +# Primary deployment: GitHub Pages (see .github/workflows/pages.yml) +# Alternative deployment: GitLab Pages (this file) + +stages: + - build + - deploy + - sync + +variables: + DEPLOY_BRANCH: "main" + PUBLIC_DIR: "." + +# Build stage - validate HTML/CSS if needed +build: + stage: build + image: node:18-alpine + script: + - echo "Building CV website..." + - | + if [ ! -f "index.html" ]; then + echo "Error: index.html not found!" + exit 1 + fi + echo "✓ index.html found" + if [ ! -f "print.css" ]; then + echo "Warning: print.css not found" + else + echo "✓ print.css found" + fi + echo "✓ Build validation complete" + artifacts: + paths: + - index.html + - print.css + - "*.JPG" + - "*.jpg" + - "*.png" + expire_in: 1 hour + only: + - main + - master + - merge_requests + +# Deploy to GitLab Pages pages: stage: deploy + image: alpine:latest script: - - cp -r * .public + - echo "Deploying to GitLab Pages..." + - | + # Copy all necessary files to public directory + mkdir -p public + cp -r index.html print.css public/ 2>/dev/null || true + # Copy images + cp -r *.JPG *.jpg *.png public/ 2>/dev/null || true + # Copy any other assets + if [ -d "assets" ]; then + cp -r assets public/ 2>/dev/null || true + fi + - echo "✓ Files copied to public directory" + - echo "Deployment complete! Site will be available at:" + - echo "https://$CI_PROJECT_NAMESPACE.gitlab.io/$CI_PROJECT_NAME" artifacts: paths: - public - rules: - - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH \ No newline at end of file + only: + - main + - master + +# Sync to GitHub (for when GitLab becomes primary) +# This job will push changes to GitHub after successful deployment +# To enable: Uncomment and configure GITHUB_SSH_PRIVATE_KEY in GitLab CI/CD variables +# sync_to_github: +# stage: sync +# image: alpine:latest +# before_script: +# - apk add --no-cache git openssh-client +# - mkdir -p ~/.ssh +# - echo "$GITHUB_SSH_PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_rsa +# - chmod 600 ~/.ssh/id_rsa +# - ssh-keyscan github.com >> ~/.ssh/known_hosts +# - eval $(ssh-agent -s) +# - ssh-add ~/.ssh/id_rsa +# script: +# - git config user.name "GitLab CI" +# - git config user.email "gitlab-ci@noreply.gitlab.com" +# - git remote add github git@github.com:pwflint/CV.git || true +# - git remote set-url github git@github.com:pwflint/CV.git +# - git push github ${CI_COMMIT_REF_NAME} || echo "Push to GitHub failed (non-critical)" +# only: +# - main +# - master +# when: on_success +# allow_failure: true diff --git a/DEPLOYMENT_MIGRATION_PLAN.md b/DEPLOYMENT_MIGRATION_PLAN.md new file mode 100644 index 0000000..e2f7dbb --- /dev/null +++ b/DEPLOYMENT_MIGRATION_PLAN.md @@ -0,0 +1,138 @@ +# Deployment Migration Plan: GitHub → GitLab + +## Current State + +### Primary Repository: GitHub (origin) +- **Deployment**: GitHub Pages via GitHub Actions +- **Workflow**: `.github/workflows/pages.yml` +- **Sync**: Manual push to GitLab (hill-st) when needed +- **Auto-sync**: `.github/workflows/sync-to-gitlab.yml` (to be configured) + +### Secondary Repository: GitLab (hill-st) +- **Deployment**: GitLab Pages (configured but not primary) +- **Workflow**: `.gitlab-ci.yml` (alternative deployment option) +- **Status**: Protected main branch, receives syncs from GitHub + +## Migration Goal + +Switch primary deployment to GitLab Pages, making: +- **GitLab (hill-st)** → Primary repository and deployment +- **GitHub (origin)** → Backup/sync repository + +## Steps Required + +### 1. Update GitLab CI/CD Configuration +- [ ] Review and finalize `.gitlab-ci.yml` for GitLab Pages deployment +- [ ] Ensure build and deploy stages are properly configured +- [ ] Test GitLab Pages deployment on a feature branch +- [ ] Verify all assets (images, CSS, JS) deploy correctly + +### 2. Update Remote Configuration +- [ ] Change local git remotes: + ```bash + git remote rename origin github-backup + git remote rename hill-st origin + ``` +- [ ] Update branch tracking to point to new origin (GitLab) +- [ ] Verify remote configuration: `git remote -v` + +### 3. Reverse Sync Workflow +- [ ] Create new workflow: `.gitlab-ci.yml` sync job (or separate pipeline) +- [ ] Set up GitLab CI/CD to push to GitHub on successful deployments +- [ ] Configure GitHub personal access token or deploy key as GitLab CI/CD variable +- [ ] Test sync from GitLab → GitHub + +### 4. Update Documentation +- [ ] Update `README.md` to reflect GitLab as primary deployment +- [ ] Update deployment instructions +- [ ] Document new workflow (GitLab → GitHub sync) +- [ ] Update any references to GitHub Pages + +### 5. GitHub Actions Cleanup +- [ ] Remove or disable `.github/workflows/sync-to-gitlab.yml` (no longer needed) +- [ ] Keep `.github/workflows/pages.yml` for reference or remove if not needed +- [ ] Consider archiving GitHub Pages deployment workflow + +### 6. GitLab Pages Configuration +- [ ] Enable GitLab Pages in repository settings +- [ ] Configure custom domain (if applicable) +- [ ] Set up SSL/TLS certificate +- [ ] Test deployment and verify site is accessible + +### 7. Migration Execution +- [ ] Push current main branch to GitLab (if not already synced) +- [ ] Merge any pending PRs on GitHub first +- [ ] Create final sync from GitHub → GitLab +- [ ] Switch remotes locally +- [ ] Update any CI/CD variables or secrets +- [ ] Deploy to GitLab Pages +- [ ] Verify deployment works correctly + +### 8. Post-Migration +- [ ] Update GitHub repository description/README to indicate it's a mirror +- [ ] Test the reverse sync (GitLab → GitHub) +- [ ] Monitor first few deployments to ensure sync works +- [ ] Update any external links/bookmarks to point to GitLab Pages URL + +## GitLab CI/CD Sync Configuration + +### Option A: Add sync job to existing `.gitlab-ci.yml` +```yaml +sync_to_github: + stage: deploy + image: alpine:latest + before_script: + - apk add --no-cache git openssh-client + - mkdir -p ~/.ssh + - echo "$GITHUB_SSH_PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_rsa + - chmod 600 ~/.ssh/id_rsa + - ssh-keyscan github.com >> ~/.ssh/known_hosts + script: + - git remote add github git@github.com:pwflint/CV.git || true + - git push github ${CI_COMMIT_REF_NAME} || true + only: + - main + when: on_success +``` + +### Option B: Separate sync pipeline +- Create dedicated sync job that runs after successful Pages deployment +- Use GitLab CI/CD variables for GitHub credentials +- Configure to run only on main branch deployments + +## Considerations + +### Branch Protection +- GitLab main branch is protected (cannot force push) +- Will need to use merge requests for all changes +- GitHub can remain less restricted as backup + +### Deployment URLs +- Update any hardcoded URLs or references +- GitLab Pages URL format: `https://[namespace].gitlab.io/[project-name]` +- Or custom domain if configured + +### Secrets Management +- Move GitHub-related secrets to GitLab CI/CD variables +- Set up GitHub personal access token or deploy key +- Store securely in GitLab's variable management + +### Rollback Plan +- Keep GitHub Actions workflow files for quick rollback if needed +- Document how to switch back if issues arise +- Maintain ability to deploy from either platform during transition + +## Timeline Recommendation + +1. **Phase 1**: Set up and test GitLab Pages deployment (1-2 days) +2. **Phase 2**: Configure reverse sync workflow (1 day) +3. **Phase 3**: Update remotes and documentation (1 day) +4. **Phase 4**: Execute migration and verify (1 day) +5. **Phase 5**: Monitor and adjust (ongoing) + +## Notes + +- LICENSE file: Currently only on GitLab, should be added to GitHub during migration +- Current workflow files can be kept for reference +- Consider keeping both deployment methods active during transition period +- Test thoroughly before making GitLab the primary diff --git a/README.md b/README.md index e36754e..f637f2d 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,12 @@ A static website version of my curriculum vitae, built with HTML and CSS. - [x] Added contact icons in header - [x] Added KALEIOPE website link in footer - [x] Removed unnecessary Jekyll dependencies +- [x] Added dark mode support with persistent theme preference +- [x] Optimized image loading with lazy loading +- [x] Added print stylesheet for professional PDF export +- [x] Added PDF export functionality +- [x] Implemented GitHub Actions workflow for GitHub Pages deployment +- [x] Added privacy-friendly analytics tracking ### Current Features - Clean, modern design @@ -26,21 +32,65 @@ A static website version of my curriculum vitae, built with HTML and CSS. - Easy navigation - Contact information readily available - Professional typography +- **Dark mode** with system preference detection and manual toggle +- **Optimized images** with lazy loading for faster page performance +- **Print-optimized** stylesheet for professional PDF generation +- **One-click PDF export** using browser's native print functionality +- **Privacy-friendly analytics** tracking page views and interactions ### Technical Details - Built with vanilla HTML and CSS - Uses Font Awesome for icons - Google Fonts for typography -- No JavaScript dependencies +- Minimal JavaScript for enhanced functionality (dark mode, PDF export, analytics) - Mobile-first design - WCAG 2.1 AA compliant +- Lazy loading images for performance +- Print stylesheet for professional output +- GitHub Actions workflow for automated deployment to GitHub Pages ## Deployment -This site is deployed using GitHub Pages. The main file is `index.html`. -## Future Improvements -- [ ] Add dark mode support -- [ ] Optimize image loading -- [ ] Add print stylesheet -- [ ] Add a PDF export option +This site is deployed using **GitHub Pages** via GitHub Actions workflow. The deployment is automated through `.github/workflows/pages.yml`. + +### Deployment Process +1. Push changes to the `main` branch +2. GitHub Actions automatically validates and builds the site +3. Site is deployed to GitHub Pages +4. Site is available at: `https://[username].github.io/[repository-name]` or your custom domain + +### Deployment Configuration +- **Primary**: GitHub Pages (automated via GitHub Actions) +- **Alternative**: GitLab Pages configuration available in `.gitlab-ci.yml` if needed +- **Manual**: Files can be deployed directly to any static hosting service + +### GitHub Pages Setup +1. Enable GitHub Pages in repository settings +2. Select source: "GitHub Actions" (not "Deploy from a branch") +3. The workflow will automatically deploy on pushes to `main` + +### Manual Deployment +If you need to deploy manually or to a different server: +- Use the files directly (they're static HTML/CSS/JS) +- Upload to any static hosting service (Netlify, Vercel, etc.) +- Configure the GitLab CI/CD pipeline for GitLab Pages (see `.gitlab-ci.yml`) + +## Configuration + +### Analytics +The analytics script (`analytics.js`) is included but requires configuration: +1. Update `ANALYTICS_ENDPOINT` in `analytics.js` with your analytics service endpoint +2. Set `ENABLE_ANALYTICS` to `true` to enable tracking, or `false` to disable + +The analytics script is privacy-friendly: +- No cookies used +- No personal data collected +- Session IDs are memory-only (not persisted) +- Respects user privacy + +### Dark Mode +Dark mode preference is stored in `localStorage` and persists across sessions. Users can toggle between light and dark themes using the moon/sun icon in the header. + +### PDF Export +Click the "Export as PDF" button to generate a PDF version of the CV. The print stylesheet ensures professional formatting when printing or saving as PDF.