diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..f8aefdc --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,37 @@ +name: CI + +on: + push: + branches: [ "main", "develop" ] + pull_request: + branches: [ "main" ] + +jobs: + test: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [18, 20, 22] + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Lint + run: npm run lint + + - name: Type check + run: npx tsc --noEmit + + - name: Build + run: npm run build \ No newline at end of file diff --git a/.github/workflows/copilot-validation.yml b/.github/workflows/copilot-validation.yml deleted file mode 100644 index 82b9af3..0000000 --- a/.github/workflows/copilot-validation.yml +++ /dev/null @@ -1,55 +0,0 @@ -name: Copilot Development Validation - -on: - push: - branches: [ main, develop ] - pull_request: - branches: [ main ] - -jobs: - validate: - runs-on: ubuntu-latest - - strategy: - matrix: - node-version: [18.x, 20.x] - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node-version }} - cache: 'npm' - - - name: Install dependencies - run: npm ci - - - name: Run linting - run: npm run lint - - - name: Type checking - run: npx tsc --noEmit - - - name: Build project - run: npm run build - - - name: Validate Copilot configuration - run: | - echo "Validating Copilot configuration files..." - test -f .github/INSTRUCTIONS.md || (echo "Missing .github/INSTRUCTIONS.md" && exit 1) - test -f .copilot/instructions.md || (echo "Missing .copilot/instructions.md" && exit 1) - test -f .copilot/dev-environment.yml || (echo "Missing .copilot/dev-environment.yml" && exit 1) - test -f .github/copilot-mcp.json || (echo "Missing .github/copilot-mcp.json" && exit 1) - echo "All Copilot configuration files are present ✅" - - - name: Build success notification - if: success() - run: | - echo "🎉 Build successful! The repository is properly configured for GitHub Copilot." - echo "📚 Repository instructions are available in .github/INSTRUCTIONS.md" - echo "🤖 Custom Copilot instructions are in .copilot/instructions.md" - echo "🛠️ Development environment is configured in .copilot/dev-environment.yml" - echo "🔧 MCP configuration is available in .github/copilot-mcp.json" \ No newline at end of file diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml deleted file mode 100644 index 6502762..0000000 --- a/.github/workflows/deploy.yml +++ /dev/null @@ -1,89 +0,0 @@ -name: Deploy to GitHub Pages - -on: - push: - branches: - - main - pull_request: - branches: - - main - workflow_dispatch: - -permissions: - contents: read - pages: write - id-token: write - -concurrency: - group: "pages" - cancel-in-progress: false - -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: 22 - cache: 'npm' - - - name: Install dependencies - run: npm ci - - - name: Setup Pages - id: setup_pages - uses: actions/configure-pages@v5 - - - name: Restore Next.js build cache - uses: actions/cache@v4 - with: - path: .next/cache - key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**.[jt]s', '**.[jt]sx', '**/*.ts', '**/*.tsx') }} - restore-keys: | - ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}- - - - name: Build (GitHub Pages) - # Ensure your build script outputs static assets to ./out - # If needed, set output: 'export' in next.config.js - run: npm run build:github-pages - env: - PAGES_BASE_PATH: ${{ steps.setup_pages.outputs.base_path }} - - - name: Add .nojekyll file - run: | - echo "Creating .nojekyll file to disable Jekyll processing" - touch out/.nojekyll - echo "Verifying .nojekyll file was created:" - ls -la out/.nojekyll - - - name: Debug build output - run: | - echo "Build output structure:" - ls -la out/ - echo "Checking _next directory (if present):" - ls -la out/_next/ || echo "_next directory not found (ensure static export)." - if [ -d out/_next/static/chunks ]; then - echo "Checking static chunks:" - ls -la out/_next/static/chunks/ | head -20 - fi - - - name: Upload artifact - uses: actions/upload-pages-artifact@v3 - with: - path: ./out - - deploy: - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest - needs: build - if: github.ref == 'refs/heads/main' - steps: - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v4 \ No newline at end of file diff --git a/.github/workflows/nextjs.yml b/.github/workflows/nextjs.yml new file mode 100644 index 0000000..6d7781a --- /dev/null +++ b/.github/workflows/nextjs.yml @@ -0,0 +1,98 @@ +# Sample workflow for building and deploying a Next.js site to GitHub Pages +# +# To get started with Next.js see: https://nextjs.org/docs/getting-started +# +name: Deploy Next.js site to Pages + +on: + # Runs on pushes targeting the default branch + push: + branches: ["main"] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. +# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + # Build job + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Detect package manager + id: detect-package-manager + run: | + if [ -f "${{ github.workspace }}/yarn.lock" ]; then + echo "manager=yarn" >> $GITHUB_OUTPUT + echo "command=install" >> $GITHUB_OUTPUT + echo "runner=yarn" >> $GITHUB_OUTPUT + exit 0 + elif [ -f "${{ github.workspace }}/package.json" ]; then + echo "manager=npm" >> $GITHUB_OUTPUT + echo "command=ci" >> $GITHUB_OUTPUT + echo "runner=npx --no-install" >> $GITHUB_OUTPUT + exit 0 + else + echo "Unable to determine package manager" + exit 1 + fi + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: "20" + cache: ${{ steps.detect-package-manager.outputs.manager }} + + - name: Setup Pages + uses: actions/configure-pages@v5 + with: + # Automatically infer Next.js configuration + # https://github.com/actions/configure-pages#next-js + static_site_generator: next + + - name: Restore cache + uses: actions/cache@v4 + with: + path: | + .next/cache + # Generate a new cache whenever packages or source files change. + key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json', '**/yarn.lock') }}-${{ hashFiles('**.[jt]s', '**.[jt]sx') }} + # If source files changed but packages didn't, rebuild from a prior cache. + restore-keys: | + ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json', '**/yarn.lock') }}- + + - name: Install dependencies + run: ${{ steps.detect-package-manager.outputs.manager }} ${{ steps.detect-package-manager.outputs.command }} + + - name: Build with Next.js + run: ${{ steps.detect-package-manager.outputs.runner }} next build + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: ./out + + # Deployment job + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 \ No newline at end of file diff --git a/.gitignore b/.gitignore index f2ee2ae..6fcf651 100644 --- a/.gitignore +++ b/.gitignore @@ -15,8 +15,8 @@ # next.js /.next/ -# The `out` directory should not be ignored by version control -# /out/ +# The `out` directory contains build artifacts and should not be committed +/out/ # production /build diff --git a/docs/github-pages-deployment.md b/docs/github-pages-deployment.md index 4ddf358..4ab7519 100644 --- a/docs/github-pages-deployment.md +++ b/docs/github-pages-deployment.md @@ -1,16 +1,16 @@ # GitHub Pages Deployment Guide -This document outlines the deployment process for CodeStorm Hub using GitHub Pages with automated GitHub Actions workflow. +This document outlines the deployment process for CodeStorm Hub using GitHub Pages with the official Next.js deployment workflow. ## Overview -CodeStorm Hub is deployed using GitHub Pages with a Next.js static export. The deployment process is fully automated through GitHub Actions, which builds and deploys the site whenever changes are pushed to the main branch. +CodeStorm Hub is deployed using GitHub Pages with Next.js static export functionality. The deployment process is fully automated through GitHub Actions using the official Next.js workflow template. ## Architecture - **Framework**: Next.js 15 with static export (`output: 'export'`) - **Deployment Platform**: GitHub Pages -- **Automation**: GitHub Actions workflow +- **Automation**: GitHub Actions workflow (official Next.js template) - **Branch**: `main` (production deployment) - **Build Output**: Static HTML/CSS/JS files in `/out` directory @@ -18,158 +18,162 @@ CodeStorm Hub is deployed using GitHub Pages with a Next.js static export. The d ### 1. Next.js Configuration (`next.config.ts`) -The application is configured for static export with GitHub Pages optimizations: +The application is configured for static export with GitHub Pages compatibility: ```typescript +import type { NextConfig } from "next"; + const nextConfig: NextConfig = { - output: 'export', - trailingSlash: true, + // Enable static export for GitHub Pages + output: "export", + + // Disable trailing slash for better GitHub Pages compatibility + trailingSlash: false, + + // Configure images for static export images: { - unoptimized: true, // Required for GitHub Pages - remotePatterns: [new URL("https://github.com/CodeStorm-Hub.png")], + unoptimized: true, + remotePatterns: [ + { + protocol: "https", + hostname: "github.com", + pathname: "/CodeStorm-Hub/**", + }, + ], }, - // GitHub Pages specific paths - basePath: process.env.NODE_ENV === 'production' ? '/CodeStorm-Hub.github.io' : '', - assetPrefix: process.env.NODE_ENV === 'production' ? '/CodeStorm-Hub.github.io/' : '', }; + +export default nextConfig; ``` -### 2. GitHub Actions Workflow (`.github/workflows/deploy.yml`) +### 2. GitHub Actions Workflow (`.github/workflows/nextjs.yml`) -Automated deployment workflow that: -- Triggers on pushes to `main` branch and pull requests -- Can be manually triggered via workflow_dispatch -- Builds the Next.js application as static files using `npm run build:github-pages` -- Creates `.nojekyll` file to disable Jekyll processing -- Deploys to GitHub Pages using official GitHub Pages action +Uses the official Next.js workflow template with: +- Automatic package manager detection (npm/yarn) +- Smart caching for faster builds +- Built-in Next.js configuration inference +- Proper permissions and concurrency handling +- Deployment to GitHub Pages using official actions -### 3. Critical Files for Deployment +### 3. Repository Settings Required + +Ensure the following GitHub repository settings are configured: -- **`.nojekyll`**: Automatically created during build to prevent GitHub from processing the site with Jekyll (critical for `_next` directory assets) -- **`404.html`**: Custom 404 page (automatically generated by Next.js) -- **Asset files**: All CSS/JS files in `_next/static/` directory with correct basePath prefixes +#### Pages Settings +1. Navigate to **Settings** → **Pages** +2. **Source**: GitHub Actions +3. The workflow will automatically create deployments + +#### Actions Permissions +1. Navigate to **Settings** → **Actions** → **General** +2. Ensure "Allow all actions and reusable workflows" is selected +3. Under "Workflow permissions", select "Read and write permissions" ## Deployment Process ### Automatic Deployment 1. **Trigger**: Push changes to the `main` branch -2. **Build**: GitHub Actions runs `npm run build:github-pages` +2. **Build**: GitHub Actions runs the Next.js build process 3. **Export**: Next.js generates static files in `/out` directory -4. **Deploy**: Files are deployed to GitHub Pages -5. **Live**: Site is available at `https://codestorm-hub.github.io/CodeStorm-Hub.github.io/` +4. **Deploy**: Files are deployed to GitHub Pages automatically +5. **Live**: Site is available at the GitHub Pages URL ### Manual Deployment You can manually trigger deployment: 1. Go to the repository's Actions tab -2. Select "Deploy to GitHub Pages" workflow +2. Select "Deploy Next.js site to Pages" workflow 3. Click "Run workflow" on the main branch -## Local Testing +## Local Development -To test the GitHub Pages build locally: +To test the build locally: ```bash # Install dependencies npm install -# Build for GitHub Pages -npm run build:github-pages +# Development server +npm run dev + +# Production build (same as CI) +npm run build # Serve the static files (optional) npx serve out ``` -## Repository Settings +## Continuous Integration -Ensure the following GitHub repository settings are configured: +A separate CI workflow (`.github/workflows/ci.yml`) runs on all pushes and pull requests to: +- Lint the codebase +- Run type checking +- Test builds across multiple Node.js versions (18, 20, 22) -### Pages Settings -1. Navigate to **Settings** → **Pages** -2. **Source**: Deploy from a branch -3. **Branch**: Select `gh-pages` (created automatically by the workflow) -4. **Folder**: `/ (root)` +## Key Features -### Actions Permissions -1. Navigate to **Settings** → **Actions** → **General** -2. Ensure "Allow all actions and reusable workflows" is selected -3. Under "Workflow permissions", select "Read and write permissions" +### Automatic Configuration +- Package manager detection (npm/yarn) +- Next.js configuration inference +- Smart caching for faster builds + +### Security & Performance +- Proper GITHUB_TOKEN permissions +- Concurrency control to prevent conflicts +- Optimized build caching +- Static file generation for fast loading + +### Monitoring +- Clear build logs in Actions tab +- Deployment status tracking +- Error reporting and debugging ## Troubleshooting ### Common Issues 1. **Build Fails** - - Check the Actions tab for error logs + - Check the Actions tab for detailed error logs - Ensure all dependencies are properly listed in `package.json` - - Verify TypeScript compilation passes locally - -2. **Assets Not Loading** - - Confirm `basePath` and `assetPrefix` are correctly configured - - Check that images use the Next.js `Image` component - - Verify links use Next.js `Link` component + - Verify TypeScript compilation passes locally with `npx tsc --noEmit` -3. **404 Errors on Page Refresh** - - This is expected behavior for client-side routing in GitHub Pages - - The custom 404.html handles fallback routing +2. **Deployment Fails** + - Verify repository Pages settings are configured for "GitHub Actions" source + - Check that workflow permissions are set correctly + - Ensure the workflow has proper `pages: write` and `id-token: write` permissions -4. **Workflow Permissions Error** - - Ensure repository has proper Actions permissions - - Check that GITHUB_TOKEN has necessary permissions +3. **404 Errors** + - Verify all pages are properly exported as static files + - Check that Next.js routing is compatible with static export + - The 404.html page is automatically generated for fallback routing ### Validation Steps After deployment, verify: - [ ] Site loads at the GitHub Pages URL -- [ ] Navigation works correctly -- [ ] Images and assets load properly -- [ ] All pages are accessible -- [ ] Responsive design works across devices -- [ ] Dark/light mode toggle functions +- [ ] All pages are accessible and properly rendered +- [ ] Images and assets load correctly +- [ ] Navigation works properly - [ ] No console errors in browser developer tools - -## Performance Optimizations - -The GitHub Pages deployment includes several optimizations: - -- **Static Generation**: All pages are pre-generated at build time -- **Asset Optimization**: Images and assets are optimized for web delivery -- **Bundle Splitting**: JavaScript is split into optimized chunks -- **CSS Optimization**: Tailwind CSS is purged of unused styles -- **Caching**: Static assets leverage browser caching - -## Monitoring - -Monitor deployment status: -- **Actions Tab**: View build and deployment logs -- **Pages Settings**: Check deployment status and URL -- **Repository Insights**: Monitor site traffic and performance +- [ ] Responsive design works across devices ## Maintenance Regular maintenance tasks: - Monitor GitHub Actions workflow runs -- Update dependencies periodically -- Review and optimize Core Web Vitals -- Test deployment after major changes -- Keep documentation updated +- Keep dependencies updated +- Review build performance and optimize as needed +- Test deployment after major Next.js or dependency updates ## Custom Domain (Optional) To use a custom domain: -1. Add a `CNAME` file to the repository root +1. Add a `CNAME` file to the repository root with your domain 2. Configure DNS records with your domain provider 3. Update the domain in repository Pages settings -4. Update `basePath` and `assetPrefix` in `next.config.ts` - -## Security Considerations - -- All builds run in isolated GitHub Actions environments -- No sensitive data is exposed in client-side code -- Dependencies are automatically scanned for vulnerabilities -- HTTPS is enforced by default on GitHub Pages +4. GitHub Pages will automatically handle HTTPS certificates --- -For questions or issues with deployment, please refer to the [GitHub Pages documentation](https://docs.github.com/en/pages) or open an issue in this repository. \ No newline at end of file +For questions or issues with deployment, please refer to the [GitHub Pages documentation](https://docs.github.com/en/pages) or [Next.js deployment documentation](https://nextjs.org/docs/deployment/static-exports). \ No newline at end of file diff --git a/next.config.ts b/next.config.ts index 6267290..ef203e3 100644 --- a/next.config.ts +++ b/next.config.ts @@ -1,22 +1,23 @@ import type { NextConfig } from "next"; -const isGitHubPages = process.env.NODE_ENV === 'production' && process.env.GITHUB_ACTIONS === 'true'; - const nextConfig: NextConfig = { - // Only enable export for GitHub Pages production builds - ...(isGitHubPages && { output: "export" }), + // Enable static export for GitHub Pages + output: "export", + + // Disable trailing slash for better GitHub Pages compatibility trailingSlash: false, + + // Configure images for static export images: { - // Only disable optimization for GitHub Pages - unoptimized: Boolean(isGitHubPages), - remotePatterns: [new URL("https://github.com/CodeStorm-Hub.png")], + unoptimized: true, + remotePatterns: [ + { + protocol: "https", + hostname: "github.com", + pathname: "/CodeStorm-Hub/**", + }, + ], }, - // GitHub Pages specific configuration - ...(isGitHubPages && { - output: "export", - basePath: process.env.PAGES_BASE_PATH, - assetPrefix: "/CodeStorm-Hub.github.io/", - }), }; export default nextConfig; diff --git a/package-lock.json b/package-lock.json index d5eca0e..142f301 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2046,7 +2046,6 @@ "integrity": "sha512-ukd93VGzaNPMAUPy0gRDSC57UuQbnH9Kussp7HBjM06YFi9uZTFhOvMSO2OKqXm1rSgzOE+pVx1k1PYHGwlc8Q==", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "csstype": "^3.0.2" } @@ -2057,7 +2056,6 @@ "integrity": "sha512-qXRuZaOsAdXKFyOhRBg6Lqqc0yay13vN7KrIg4L7N4aaHN68ma9OK3NE1BoDFgFOTfM7zg+3/8+2n8rLUH3OKQ==", "devOptional": true, "license": "MIT", - "peer": true, "peerDependencies": { "@types/react": "^19.0.0" } @@ -2108,7 +2106,6 @@ "integrity": "sha512-EHrrEsyhOhxYt8MTg4zTF+DJMuNBzWwgvvOYNj/zm1vnaD/IC5zCXFehZv94Piqa2cRFfXrTFxIvO95L7Qc/cw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.44.1", "@typescript-eslint/types": "8.44.1", @@ -2626,7 +2623,6 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -3516,7 +3512,6 @@ "integrity": "sha512-hB4FIzXovouYzwzECDcUkJ4OcfOEkXTv2zRY6B9bkwjx/cprAq0uvm1nl7zvQ0/TsUk0zQiN4uPfJpB9m+rPMQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -3691,7 +3686,6 @@ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -5812,7 +5806,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -5822,7 +5815,6 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", "license": "MIT", - "peer": true, "dependencies": { "scheduler": "^0.26.0" }, @@ -6595,7 +6587,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -6745,7 +6736,6 @@ "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/package.json b/package.json index 0afc8d0..86789ce 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,6 @@ "scripts": { "dev": "next dev --turbopack", "build": "next build --turbopack", - "build:github-pages": "NODE_ENV=production GITHUB_ACTIONS=true next build --turbopack", "start": "next start", "lint": "eslint" },