feat: initialize HEC IA Wiki with Docker setup, build process, and content structure
- Add .dockerignore t - Create Gitea Action to build and publish image - Update Dockerfile to include build steps and health check - Revise README.md - Modify config.ts for site-specific settings - Enhance content.config.ts to define collections for events, workshops, news, and technical articles
This commit is contained in:
@@ -1,8 +1,27 @@
|
||||
# Ignore Astro files
|
||||
*.astro
|
||||
# Development files
|
||||
.git/
|
||||
.gitignore
|
||||
.vscode/
|
||||
.DS_Store
|
||||
|
||||
# Ignore node_modules directory
|
||||
# Cache and temp files
|
||||
.astro/
|
||||
node_modules/
|
||||
|
||||
# Ignore build output
|
||||
# Build output (will be rebuilt in Docker)
|
||||
dist/
|
||||
|
||||
# Environment files
|
||||
.env
|
||||
.env.*
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
# Documentation (optional - comment if needed in image)
|
||||
# *.md
|
||||
# !README.md
|
||||
46
.gitea/workflows/build-image.yml
Normal file
46
.gitea/workflows/build-image.yml
Normal file
@@ -0,0 +1,46 @@
|
||||
name: Build and Push Docker Image - HEC IA Wiki
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
|
||||
env:
|
||||
REGISTRY: "gitea.vorpax.dev"
|
||||
IMAGE_NAME: "vorpax_admin/hecia-wiki"
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Log in to Gitea Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ gitea.actor }}
|
||||
password: ${{ secrets.REGISTRY_TOKEN }}
|
||||
|
||||
- name: Extract metadata (tags, labels)
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
tags: |
|
||||
type=ref,event=branch
|
||||
type=sha,prefix=
|
||||
type=raw,value=latest,enable=${{ gitea.ref == format('refs/heads/{0}', 'main') || gitea.ref == format('refs/heads/{0}', 'master') }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
19
Dockerfile
19
Dockerfile
@@ -5,13 +5,32 @@ WORKDIR /app
|
||||
# Install pnpm
|
||||
RUN corepack enable && corepack prepare pnpm@latest --activate
|
||||
|
||||
# Copy package files
|
||||
COPY package.json pnpm-lock.yaml ./
|
||||
|
||||
# Install dependencies
|
||||
RUN pnpm install --frozen-lockfile
|
||||
|
||||
# Copy all source files (respecting .dockerignore)
|
||||
COPY . .
|
||||
|
||||
# Build the application
|
||||
# Note: The build script includes: astro check && astro build && pagefind --site dist && cp -r dist/pagefind public/
|
||||
RUN pnpm run build
|
||||
|
||||
# Runtime stage for serving the application
|
||||
FROM nginx:mainline-alpine-slim AS runtime
|
||||
|
||||
# Copy the built site from dist directory
|
||||
COPY --from=base /app/dist /usr/share/nginx/html
|
||||
|
||||
# The build script copies pagefind to public/, so we need to copy it back to dist for the runtime
|
||||
# Copy pagefind if it exists in public/
|
||||
COPY --from=base /app/public/pagefind /usr/share/nginx/html/pagefind
|
||||
|
||||
# Expose port 80
|
||||
EXPOSE 80
|
||||
|
||||
# Add healthcheck
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||||
CMD wget --no-verbose --tries=1 --spider http://localhost/ || exit 1
|
||||
|
||||
238
README.md
238
README.md
@@ -1,53 +1,214 @@
|
||||
# AstroPaper 📄
|
||||
# HEC IA Wiki 🤖
|
||||
|
||||

|
||||
[](https://www.figma.com/community/file/1356898632249991861)
|
||||

|
||||

|
||||
[](https://conventionalcommits.org)
|
||||
[](http://commitizen.github.io/cz-cli/)
|
||||

|
||||
|
||||
AstroPaper is a minimal, responsive, accessible and SEO-friendly Astro blog theme. This theme is designed and crafted based on [my personal blog](https://satnaing.dev/blog).
|
||||
The official wiki and knowledge base for HEC IA student association. Built with [Astro](https://astro.build/) and the [AstroPaper](https://github.com/satnaing/astro-paper) theme.
|
||||
|
||||
Read [the blog posts](https://astro-paper.pages.dev/posts/) or check [the README Documentation Section](#-documentation) for more info.
|
||||
## 📚 About
|
||||
|
||||
## 🔥 Features
|
||||
This wiki serves as a central hub for HEC IA's content, including:
|
||||
|
||||
- [x] type-safe markdown
|
||||
- [x] super fast performance
|
||||
- [x] accessible (Keyboard/VoiceOver)
|
||||
- [x] responsive (mobile ~ desktops)
|
||||
- [x] SEO-friendly
|
||||
- [x] light & dark mode
|
||||
- [x] fuzzy search
|
||||
- [x] draft posts & pagination
|
||||
- [x] sitemap & rss feed
|
||||
- [x] followed best practices
|
||||
- [x] highly customizable
|
||||
- [x] dynamic OG image generation for blog posts [#15](https://github.com/satnaing/astro-paper/pull/15) ([Blog Post](https://astro-paper.pages.dev/posts/dynamic-og-image-generation-in-astropaper-blog-posts/))
|
||||
- **Events**: Information about upcoming and past events
|
||||
- **Workshops**: Hands-on technical workshops and tutorials
|
||||
- **News**: Latest updates and announcements from HEC IA
|
||||
- **Technical Deep Dives**: In-depth technical articles on AI topics
|
||||
|
||||
_Note: I've tested screen-reader accessibility of AstroPaper using **VoiceOver** on Mac and **TalkBack** on Android. I couldn't test all other screen-readers out there. However, accessibility enhancements in AstroPaper should be working fine on others as well._
|
||||
## 🚀 Quick Start
|
||||
|
||||
## ✅ Lighthouse Score
|
||||
### Prerequisites
|
||||
|
||||
<p align="center">
|
||||
<a href="https://pagespeed.web.dev/report?url=https%3A%2F%2Fastro-paper.pages.dev%2F&form_factor=desktop">
|
||||
<img width="710" alt="AstroPaper Lighthouse Score" src="AstroPaper-lighthouse-score.svg">
|
||||
</a>
|
||||
</p>
|
||||
- Node.js 18+
|
||||
- npm or pnpm
|
||||
|
||||
## 🚀 Project Structure
|
||||
### Installation
|
||||
|
||||
Inside of AstroPaper, you'll see the following folders and files:
|
||||
```bash
|
||||
# Clone the repository
|
||||
git clone https://github.com/hec-ia/wiki.git
|
||||
cd wiki
|
||||
|
||||
# Install dependencies
|
||||
npm install
|
||||
|
||||
# Start development server
|
||||
npm run dev
|
||||
```
|
||||
|
||||
The site will be available at `http://localhost:4321`
|
||||
|
||||
### Building for Production
|
||||
|
||||
```bash
|
||||
# Build the site
|
||||
npm run build
|
||||
|
||||
# Preview the build
|
||||
npm run preview
|
||||
```
|
||||
|
||||
## 📝 Adding Content
|
||||
|
||||
### Events
|
||||
|
||||
Create a new markdown file in `src/data/events/`:
|
||||
|
||||
```markdown
|
||||
---
|
||||
title: "Your Event Title"
|
||||
description: "Event description"
|
||||
author: "HEC IA"
|
||||
pubDatetime: 2026-01-15T10:00:00Z
|
||||
eventDate: 2026-02-05T14:00:00Z
|
||||
eventEndDate: 2026-02-05T18:00:00Z
|
||||
location: "Event Location"
|
||||
tags: ["tag1", "tag2"]
|
||||
featured: true
|
||||
registrationLink: "https://registration-link.com"
|
||||
---
|
||||
|
||||
Your event content here...
|
||||
```
|
||||
|
||||
### Workshops
|
||||
|
||||
Create a new markdown file in `src/data/workshops/`:
|
||||
|
||||
```markdown
|
||||
---
|
||||
title: "Workshop Title"
|
||||
description: "Workshop description"
|
||||
author: "HEC IA"
|
||||
pubDatetime: 2026-01-15T10:00:00Z
|
||||
workshopDate: 2026-02-05T14:00:00Z
|
||||
duration: "3 hours"
|
||||
level: "beginner" # beginner, intermediate, or advanced
|
||||
tags: ["machine-learning", "python"]
|
||||
featured: true
|
||||
materials: "https://github.com/hec-ia/workshop-materials"
|
||||
---
|
||||
|
||||
Your workshop content here...
|
||||
```
|
||||
|
||||
### News
|
||||
|
||||
Create a new markdown file in `src/data/news/`:
|
||||
|
||||
```markdown
|
||||
---
|
||||
title: "News Title"
|
||||
description: "News description"
|
||||
author: "HEC IA"
|
||||
pubDatetime: 2026-01-25T10:00:00Z
|
||||
tags: ["news", "announcement"]
|
||||
featured: true
|
||||
---
|
||||
|
||||
Your news content here...
|
||||
```
|
||||
|
||||
### Technical Deep Dives
|
||||
|
||||
Create a new markdown file in `src/data/technical/`:
|
||||
|
||||
```markdown
|
||||
---
|
||||
title: "Technical Article Title"
|
||||
description: "Article description"
|
||||
author: "HEC IA Technical Team"
|
||||
pubDatetime: 2026-01-28T10:00:00Z
|
||||
tags: ["deep-learning", "nlp"]
|
||||
difficulty: "advanced" # beginner, intermediate, or advanced
|
||||
readingTime: "25 min"
|
||||
featured: true
|
||||
---
|
||||
|
||||
Your technical content here...
|
||||
```
|
||||
|
||||
## 🎨 Customization
|
||||
|
||||
### Site Configuration
|
||||
|
||||
Edit `src/config.ts` to customize:
|
||||
|
||||
- Site title and description
|
||||
- Author information
|
||||
- Social links
|
||||
- Posts per page
|
||||
- And more...
|
||||
|
||||
### Theme Colors
|
||||
|
||||
The site uses Tailwind CSS. Customize colors in:
|
||||
|
||||
- `src/styles/base.css` for global styles
|
||||
- `tailwind.config.js` for theme configuration
|
||||
|
||||
## 📂 Project Structure
|
||||
|
||||
```bash
|
||||
/
|
||||
├── public/
|
||||
│ ├── pagefind/ # auto-generated when build
|
||||
│ ├── favicon.svg
|
||||
│ └── astropaper-og.jpg
|
||||
│ └── assets/ # Static assets
|
||||
├── src/
|
||||
│ ├── assets/
|
||||
│ ├── assets/ # SVG icons and images
|
||||
│ ├── components/ # Astro components
|
||||
│ ├── data/ # Content collections
|
||||
│ │ ├── events/
|
||||
│ │ ├── workshops/
|
||||
│ │ ├── news/
|
||||
│ │ └── technical/
|
||||
│ ├── layouts/ # Page layouts
|
||||
│ ├── pages/ # Route pages
|
||||
│ ├── styles/ # Global styles
|
||||
│ ├── utils/ # Utility functions
|
||||
│ ├── config.ts # Site configuration
|
||||
│ └── content.config.ts # Content collections config
|
||||
├── astro.config.ts
|
||||
├── package.json
|
||||
└── README.md
|
||||
```
|
||||
|
||||
## 🧞 Available Commands
|
||||
|
||||
| Command | Action |
|
||||
| :--------------------- | :----------------------------------------------- |
|
||||
| `npm install` | Installs dependencies |
|
||||
| `npm run dev` | Starts local dev server at `localhost:4321` |
|
||||
| `npm run build` | Build your production site to `./dist/` |
|
||||
| `npm run preview` | Preview your build locally, before deploying |
|
||||
| `npm run format:check` | Check code format with Prettier |
|
||||
| `npm run format` | Format codes with Prettier |
|
||||
| `npm run sync` | Generates TypeScript types for all Astro modules |
|
||||
| `npm run lint` | Lint with ESLint |
|
||||
|
||||
## 🤝 Contributing
|
||||
|
||||
Contributions are welcome! Please feel free to submit a Pull Request.
|
||||
|
||||
1. Fork the repository
|
||||
2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
|
||||
3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
|
||||
4. Push to the branch (`git push origin feature/AmazingFeature`)
|
||||
5. Open a Pull Request
|
||||
|
||||
## 📄 License
|
||||
|
||||
This project is licensed under the MIT License - see the LICENSE file for details.
|
||||
|
||||
## 🙏 Acknowledgments
|
||||
|
||||
Built with:
|
||||
|
||||
- [Astro](https://astro.build/) - The web framework for content-driven websites
|
||||
- [AstroPaper](https://github.com/satnaing/astro-paper) - The base theme
|
||||
- [Tailwind CSS](https://tailwindcss.com/) - For styling
|
||||
- [TypeScript](https://www.typescriptlang.org/) - For type safety
|
||||
|
||||
---
|
||||
|
||||
Made with ❤️ by HEC IA
|
||||
│ │ ├── icons/
|
||||
│ │ └── images/
|
||||
│ ├── components/
|
||||
@@ -65,7 +226,8 @@ Inside of AstroPaper, you'll see the following folders and files:
|
||||
│ ├── env.d.ts
|
||||
│ └── remark-collapse.d.ts
|
||||
└── astro.config.ts
|
||||
```
|
||||
|
||||
````
|
||||
|
||||
Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name.
|
||||
|
||||
@@ -111,7 +273,7 @@ yarn create astro --template satnaing/astro-paper
|
||||
|
||||
# bun
|
||||
bun create astro@latest -- --template satnaing/astro-paper
|
||||
```
|
||||
````
|
||||
|
||||
Then start the project by running the following commands:
|
||||
|
||||
@@ -151,7 +313,7 @@ All commands are run from the root of the project, from a terminal:
|
||||
> **_Note!_** For `Docker` commands we must have it [installed](https://docs.docker.com/engine/install/) in your machine.
|
||||
|
||||
| Command | Action |
|
||||
| :----------------------------------- | :------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| :------------------------------------ | :------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `pnpm install` | Installs dependencies |
|
||||
| `pnpm run dev` | Starts local dev server at `localhost:4321` |
|
||||
| `pnpm run build` | Build your production site to `./dist/` |
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
export const SITE = {
|
||||
website: "https://astro-paper.pages.dev/", // replace this with your deployed domain
|
||||
author: "Sat Naing",
|
||||
profile: "https://satnaing.dev/",
|
||||
desc: "A minimal, responsive and SEO-friendly Astro blog theme.",
|
||||
title: "AstroPaper",
|
||||
ogImage: "astropaper-og.jpg",
|
||||
website: "https://wiki.hec-ia.com/", // replace this with your deployed domain
|
||||
author: "HEC IA",
|
||||
profile: "https://wiki.hec-ia.com/about",
|
||||
desc: "HEC IA student association wiki - Events, workshops, news, and technical deep dives on artificial intelligence.",
|
||||
title: "HEC IA Wiki",
|
||||
ogImage: "hec-ia-og.jpg",
|
||||
lightAndDarkMode: true,
|
||||
postPerIndex: 4,
|
||||
postPerPage: 4,
|
||||
@@ -14,10 +14,10 @@ export const SITE = {
|
||||
editPost: {
|
||||
enabled: true,
|
||||
text: "Edit page",
|
||||
url: "https://github.com/satnaing/astro-paper/edit/main/",
|
||||
url: "https://github.com/hec-ia/wiki/edit/main/",
|
||||
},
|
||||
dynamicOgImage: true,
|
||||
dir: "ltr", // "rtl" | "auto"
|
||||
lang: "en", // html lang code. Set this empty and default will be "en"
|
||||
timezone: "Asia/Bangkok", // Default global timezone (IANA format) https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
||||
timezone: "Europe/Paris", // Default global timezone (IANA format) https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
||||
} as const;
|
||||
|
||||
@@ -3,6 +3,10 @@ import { glob } from "astro/loaders";
|
||||
import { SITE } from "@/config";
|
||||
|
||||
export const BLOG_PATH = "src/data/blog";
|
||||
export const EVENTS_PATH = "src/data/events";
|
||||
export const WORKSHOPS_PATH = "src/data/workshops";
|
||||
export const NEWS_PATH = "src/data/news";
|
||||
export const TECHNICAL_PATH = "src/data/technical";
|
||||
|
||||
const blog = defineCollection({
|
||||
loader: glob({ pattern: "**/[^_]*.md", base: `./${BLOG_PATH}` }),
|
||||
@@ -23,4 +27,90 @@ const blog = defineCollection({
|
||||
}),
|
||||
});
|
||||
|
||||
export const collections = { blog };
|
||||
const events = defineCollection({
|
||||
loader: glob({ pattern: "**/[^_]*.md", base: `./${EVENTS_PATH}` }),
|
||||
schema: ({ image }) =>
|
||||
z.object({
|
||||
author: z.string().default(SITE.author),
|
||||
pubDatetime: z.date(),
|
||||
eventDate: z.date(),
|
||||
eventEndDate: z.date().optional(),
|
||||
location: z.string().optional(),
|
||||
modDatetime: z.date().optional().nullable(),
|
||||
title: z.string(),
|
||||
featured: z.boolean().optional(),
|
||||
draft: z.boolean().optional(),
|
||||
tags: z.array(z.string()).default(["event"]),
|
||||
ogImage: image().or(z.string()).optional(),
|
||||
description: z.string(),
|
||||
canonicalURL: z.string().optional(),
|
||||
hideEditPost: z.boolean().optional(),
|
||||
timezone: z.string().optional(),
|
||||
registrationLink: z.string().optional(),
|
||||
}),
|
||||
});
|
||||
|
||||
const workshops = defineCollection({
|
||||
loader: glob({ pattern: "**/[^_]*.md", base: `./${WORKSHOPS_PATH}` }),
|
||||
schema: ({ image }) =>
|
||||
z.object({
|
||||
author: z.string().default(SITE.author),
|
||||
pubDatetime: z.date(),
|
||||
workshopDate: z.date(),
|
||||
duration: z.string().optional(),
|
||||
level: z.enum(["beginner", "intermediate", "advanced"]).optional(),
|
||||
modDatetime: z.date().optional().nullable(),
|
||||
title: z.string(),
|
||||
featured: z.boolean().optional(),
|
||||
draft: z.boolean().optional(),
|
||||
tags: z.array(z.string()).default(["workshop"]),
|
||||
ogImage: image().or(z.string()).optional(),
|
||||
description: z.string(),
|
||||
canonicalURL: z.string().optional(),
|
||||
hideEditPost: z.boolean().optional(),
|
||||
timezone: z.string().optional(),
|
||||
materials: z.string().optional(),
|
||||
}),
|
||||
});
|
||||
|
||||
const news = defineCollection({
|
||||
loader: glob({ pattern: "**/[^_]*.md", base: `./${NEWS_PATH}` }),
|
||||
schema: ({ image }) =>
|
||||
z.object({
|
||||
author: z.string().default(SITE.author),
|
||||
pubDatetime: z.date(),
|
||||
modDatetime: z.date().optional().nullable(),
|
||||
title: z.string(),
|
||||
featured: z.boolean().optional(),
|
||||
draft: z.boolean().optional(),
|
||||
tags: z.array(z.string()).default(["news"]),
|
||||
ogImage: image().or(z.string()).optional(),
|
||||
description: z.string(),
|
||||
canonicalURL: z.string().optional(),
|
||||
hideEditPost: z.boolean().optional(),
|
||||
timezone: z.string().optional(),
|
||||
}),
|
||||
});
|
||||
|
||||
const technical = defineCollection({
|
||||
loader: glob({ pattern: "**/[^_]*.md", base: `./${TECHNICAL_PATH}` }),
|
||||
schema: ({ image }) =>
|
||||
z.object({
|
||||
author: z.string().default(SITE.author),
|
||||
pubDatetime: z.date(),
|
||||
modDatetime: z.date().optional().nullable(),
|
||||
title: z.string(),
|
||||
featured: z.boolean().optional(),
|
||||
draft: z.boolean().optional(),
|
||||
tags: z.array(z.string()).default(["technical"]),
|
||||
ogImage: image().or(z.string()).optional(),
|
||||
description: z.string(),
|
||||
canonicalURL: z.string().optional(),
|
||||
hideEditPost: z.boolean().optional(),
|
||||
timezone: z.string().optional(),
|
||||
difficulty: z.enum(["beginner", "intermediate", "advanced"]).optional(),
|
||||
readingTime: z.string().optional(),
|
||||
}),
|
||||
});
|
||||
|
||||
export const collections = { blog, events, workshops, news, technical };
|
||||
|
||||
Reference in New Issue
Block a user