diff --git a/.github/workflows/deploy-pages.yml b/.github/workflows/deploy-pages.yml new file mode 100644 index 0000000..bef8933 --- /dev/null +++ b/.github/workflows/deploy-pages.yml @@ -0,0 +1,211 @@ +name: Deploy to GitHub Pages + +on: + push: + branches: + - main + pull_request: + branches: + - main + workflow_dispatch: + +# Allow one concurrent deployment +concurrency: + group: pages-${{ github.ref }} + cancel-in-progress: true + +# Sets permissions of the GITHUB_TOKEN +permissions: + contents: read + pages: write + id-token: write + pull-requests: write + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Full history for git-based features + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: 9 + + - name: Get pnpm store directory + id: pnpm-cache + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT + + - name: Setup pnpm cache + uses: actions/cache@v4 + with: + path: ${{ steps.pnpm-cache.outputs.STORE_PATH }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build site + run: | + # Set base URL for PR previews + if [ "${{ github.event_name }}" == "pull_request" ]; then + echo "Building PR preview..." + export BASE_URL="/docs-ng/pr-${{ github.event.pull_request.number }}/" + else + echo "Building production site..." + export BASE_URL="/docs-ng/" + fi + pnpm run docs:build + env: + NODE_ENV: production + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: docs/.vitepress/dist + + deploy-production: + needs: build + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + runs-on: ubuntu-latest + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 + + - name: Comment on related PRs + uses: actions/github-script@v7 + with: + script: | + const { data: prs } = await github.rest.pulls.list({ + owner: context.repo.owner, + repo: context.repo.repo, + state: 'open', + base: 'main' + }); + + for (const pr of prs) { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number, + body: `โœ… Production deployment updated!\n\nView at: ${{ steps.deployment.outputs.page_url }}` + }); + } + + deploy-preview: + needs: build + if: github.event_name == 'pull_request' + runs-on: ubuntu-latest + steps: + - name: Download artifact + uses: actions/download-artifact@v4 + with: + name: github-pages + path: ./preview + + - name: Extract artifact + run: | + cd preview + tar -xf artifact.tar + rm artifact.tar + + - name: Deploy PR Preview + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./preview + destination_dir: pr-${{ github.event.pull_request.number }} + keep_files: false + + - name: Comment PR + uses: actions/github-script@v7 + with: + script: | + const prNumber = context.issue.number; + const previewUrl = `https://${{ github.repository_owner }}.github.io/docs-ng/pr-${prNumber}/`; + + // Find existing preview comment + const { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + }); + + const botComment = comments.find(comment => + comment.user.type === 'Bot' && + comment.body.includes('๐Ÿ“ Documentation Preview') + ); + + const commentBody = `## ๐Ÿ“ Documentation Preview + + Preview deployment is ready! ๐Ÿš€ + + **Preview URL:** ${previewUrl} + + The preview will be updated automatically with each new commit. + + --- + Built with commit ${context.sha.substring(0, 7)}`; + + if (botComment) { + // Update existing comment + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: botComment.id, + body: commentBody + }); + } else { + // Create new comment + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + body: commentBody + }); + } + + cleanup-preview: + if: github.event_name == 'pull_request' && github.event.action == 'closed' + runs-on: ubuntu-latest + steps: + - name: Checkout gh-pages branch + uses: actions/checkout@v4 + with: + ref: gh-pages + + - name: Remove preview directory + run: | + rm -rf pr-${{ github.event.pull_request.number }} + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add . + git commit -m "chore: cleanup preview for PR #${{ github.event.pull_request.number }}" || echo "No changes to commit" + git push + + - name: Comment cleanup + uses: actions/github-script@v7 + with: + script: | + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: '๐Ÿงน Preview deployment cleaned up.' + }); \ No newline at end of file diff --git a/README.md b/README.md index eaa9e21..b376447 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,21 @@ See `scripts/tests/README.md` for more details. See `scripts/README.md` for documentation aggregation details. +## GitHub Pages Deployment + +The documentation site is automatically deployed to GitHub Pages: + +- **Production**: Automatically deployed when changes are merged to `main` + - URL: https://gardenlinux.github.io/docs-ng/ +- **PR Previews**: Each pull request gets its own preview deployment + - URL: https://gardenlinux.github.io/docs-ng/pr-{PR_NUMBER}/ + - Automatically updated with each commit + - Cleaned up when PR is closed + +The workflow is configured in `.github/workflows/deploy-pages.yml`. + +For detailed information about the deployment system, see the [GitHub Pages Deployment Guide](docs/contributing/github-pages-deployment.md). + ## Commands Run `make help` for all available commands. diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index 73fd56c..87c8916 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -1,9 +1,130 @@ import { defineConfig } from "vitepress"; +// Get base URL from environment variable (for GitHub Pages deployment) +const base = process.env.BASE_URL || '/'; + +// Shared sidebar for all documentation categories +const documentationSidebar = [ + { + text: "Tutorials", + collapsed: true, + items: [ + { text: "Overview", link: "/tutorials/" }, + { text: "First Boot - AWS", link: "/tutorials/first-boot-aws" }, + { text: "First Boot - Azure", link: "/tutorials/first-boot-azure" }, + { text: "First Boot - Bare Metal", link: "/tutorials/first-boot-bare-metal" }, + { text: "First Boot - GCP", link: "/tutorials/first-boot-gcp" }, + { text: "First Boot - KVM", link: "/tutorials/first-boot-kvm" }, + { text: "First Boot - Lima", link: "/tutorials/first-boot-lima" }, + { text: "First Boot - OCI", link: "/tutorials/first-boot-oci" }, + { text: "First Boot - OpenStack", link: "/tutorials/first-boot-openstack" }, + ], + }, + { + text: "How-to Guides", + collapsed: true, + items: [ + { text: "Overview", link: "/how-to/" }, + { text: "Choosing Flavors", link: "/how-to/choosing-flavors" }, + { text: "Getting Images", link: "/how-to/getting-images" }, + { text: "Initial Configuration", link: "/how-to/initial-configuration" }, + { text: "System Management", link: "/how-to/system-management" }, + { + text: "Customization", + collapsed: true, + items: [ + { text: "Overview", link: "/how-to/customization/" }, + { text: "Building Features", link: "/how-to/customization/building-features" }, + { text: "Building Flavors", link: "/how-to/customization/building-flavors" }, + { text: "Testing Builds", link: "/how-to/customization/testing-builds" }, + ], + }, + { + text: "Platform-Specific", + collapsed: true, + items: [ + { text: "Overview", link: "/how-to/platform-specific/" }, + { text: "AWS", link: "/how-to/platform-specific/aws" }, + { text: "Azure", link: "/how-to/platform-specific/azure" }, + { text: "Bare Metal", link: "/how-to/platform-specific/bare-metal" }, + { text: "Gardener", link: "/how-to/platform-specific/gardener" }, + { text: "GCP", link: "/how-to/platform-specific/gcp" }, + { text: "KVM", link: "/how-to/platform-specific/kvm" }, + { text: "Lima", link: "/how-to/platform-specific/lima" }, + { text: "OCI/Containers", link: "/how-to/platform-specific/oci" }, + { text: "OpenStack", link: "/how-to/platform-specific/openstack" }, + { text: "VMware", link: "/how-to/platform-specific/vmware" }, + ], + }, + { + text: "Security", + collapsed: true, + items: [ + { text: "Overview", link: "/how-to/security/" }, + { text: "Secure Boot", link: "/how-to/security/secure-boot" }, + { text: "SSH Hardening", link: "/how-to/security/ssh-hardening" }, + { text: "Time Configuration", link: "/how-to/security/time-configuration" }, + ], + }, + ], + }, + { + text: "Explanation", + collapsed: true, + items: [ + { text: "Overview", link: "/explanation/" }, + { text: "Architecture", link: "/explanation/architecture" }, + { text: "Design Decisions", link: "/explanation/design-decisions" }, + { text: "Flavors and Features", link: "/explanation/flavors-and-features" }, + { text: "Image Types", link: "/explanation/image-types" }, + { text: "Release Cadence", link: "/explanation/release-cadence" }, + { text: "Security Posture", link: "/explanation/security-posture" }, + { text: "Use Cases", link: "/explanation/use-cases" }, + ], + }, + { + text: "Reference", + collapsed: true, + items: [ + { text: "Overview", link: "/reference/" }, + { text: "Feature Glossary", link: "/reference/feature-glossary" }, + { text: "Flavor Matrix", link: "/reference/flavor-matrix" }, + { text: "Image Formats", link: "/reference/image-formats" }, + { text: "Kernels & Modules", link: "/reference/kernels-and-modules" }, + { text: "Platform Compatibility", link: "/reference/platform-compatibility" }, + { + text: "API", + collapsed: true, + items: [ + { text: "Overview", link: "/reference/api/" }, + { text: "CLI", link: "/reference/api/cli" }, + { text: "Python Library", link: "/reference/api/python-lib" }, + ], + }, + { + text: "Releases", + collapsed: true, + items: [ + { text: "Overview", link: "/reference/releases/" }, + { text: "Maintained Releases", link: "/reference/releases/maintained-releases" }, + { text: "Release Notes", link: "/reference/releases/release-notes" }, + ], + }, + ], + }, +]; + // https://vitepress.dev/reference/site-config export default defineConfig({ + base, title: "Garden Linux", // description: "Operating system built for cloud native workloads.", + ignoreDeadLinks: [ + // Ignore dead links in legacy documentation + /\/how-to\/troubleshooting\//, + /localhost/, + /\/projects\/gardenlinux\/02_operators\/deployment/, + ], head: [ [ "link", @@ -33,39 +154,43 @@ export default defineConfig({ dark: ".vitepress/theme/assets/gardenlinux-logo.svg", }, nav: [ - { text: "Home", link: "/" }, - { text: "Quick Start", link: "/users/quickstart" }, + { text: "Start Here", link: "/" }, { - text: "Docs", + text: "Documentation", items: [ { - text: "User Docs", - items: [ - { text: "Quickstart", link: "/users/quickstart" }, - { text: "Installation Guide", link: "/users/installation" }, - { text: "Build an Image", link: "/users/build-image" }, - ], + text: "Tutorials", + link: "/tutorials/", }, { - text: "Technical Documentation", - items: [ - { - text: "Garden Linux", - link: "/projects/gardenlinux/introduction/index", - }, - { text: "Builder", link: "/projects/builder/getting_started" }, - { - text: "Python Library", - link: "/projects/python-gardenlinux-lib/index", - }, - ], + text: "How-to Guides", + link: "/how-to/", }, { - text: "Contributing", - link: "/contributing/", + text: "Explanation", + link: "/explanation/", + }, + { + text: "Reference", + link: "/reference/", + }, + ], + }, + { + text: "Legacy Docs", + items: [ + { + text: "Garden Linux", + link: "/projects/gardenlinux/introduction/index", + }, + { text: "Builder", link: "/projects/builder/getting_started" }, + { + text: "Python Library", + link: "/projects/python-gardenlinux-lib/index", }, ], }, + { text: "Contributing", link: "/contributing/" }, ], // footer: { @@ -74,40 +199,21 @@ export default defineConfig({ // }, sidebar: { - // Default sidebar for root pages - "/": [ - { - text: "Getting Started", - items: [{ text: "Quick Start", link: "/users/quickstart" }], - }, - { - text: "Usage Docs", - items: [ - { text: "Installation Guide", link: "/users/installation" }, - { text: "Build an Image", link: "/users/build-image" }, - ], - }, - { - text: "Technical Documentation", - items: [ - { - text: "Garden Linux", - link: "/projects/gardenlinux/introduction/index", - }, - { text: "Builder", link: "/projects/builder/getting_started" }, - { - text: "Python Library", - link: "/projects/python-gardenlinux-lib/index", - }, - ], - }, + // Shared sidebar for all documentation categories + "/tutorials/": documentationSidebar, + "/how-to/": documentationSidebar, + "/explanation/": documentationSidebar, + "/reference/": documentationSidebar, + + // Contributing section + "/contributing/": [ { text: "Contributing", - collapsed: true, items: [ + { text: "Overview", link: "/contributing/" }, { - text: "Development Environment", - link: "/contributing/dev-environment", + text: "Documentation Guide", + link: "/contributing/documentation-guide", }, { text: "Building an Image", link: "/contributing/building-image" }, { text: "Testing an Image", link: "/contributing/testing-image" }, @@ -117,15 +223,11 @@ export default defineConfig({ text: "Dependency Policy", link: "/contributing/dependency-policy", }, - { - text: "Documentation Guide", - link: "/contributing/documentation-guide", - }, ], }, ], - // Garden Linux project docs + // Legacy documentation (temporary, for backward compatibility) "/projects/gardenlinux/": [ { text: "Introduction", diff --git a/docs/.vitepress/config.mts.backup b/docs/.vitepress/config.mts.backup deleted file mode 100644 index b03c61d..0000000 --- a/docs/.vitepress/config.mts.backup +++ /dev/null @@ -1,337 +0,0 @@ -import { defineConfig } from 'vitepress' -import { fileURLToPath, URL } from 'node:url' - -// https://vitepress.dev/reference/site-config -export default defineConfig({ - title: "Gardenlinux Documentation", - description: "All your documentation need - in one place", - base: process.env.VITE_PUBLIC_BASE_PATH || '', - srcDir: 'docs', - cleanUrls: true, - head: [ - ['link', { rel: 'icon', type: 'image/png', href: '/favicon-96x96.png', sizes: '96x96' }], - ['link', { rel: 'icon', type: 'image/svg+xml', href: '/favicon.svg' }], - ['link', { rel: 'shortcut icon', href: '/favicon.ico' }], - ['link', { rel: 'apple-touch-icon', sizes: '180x180', href: '/apple-touch-icon.png' }], - ['link', { rel: 'manifest', href: '/site.webmanifest' }], - ['meta', {name: 'theme-color', content: '#009f76'}], - ['meta', {property: 'og:type', content: 'website'}], - ['meta', {property: 'og:site_name', content: 'Garden Linux'}], - [ - 'meta', - { - property: 'og:image', - content: 'https://raw.githubusercontent.com/gardenlinux/gardenlinux/main/logo/gardenlinux-logo-black-text.svg' - } - ], - ['meta', {property: 'og:url', content: 'https://gardenlinux.io/'}], - ], - themeConfig: { - // https://vitepress.dev/reference/default-theme-config - logo: { - light: '/gardenlinux-logo.svg', - dark: '/gardenlinux-logo.svg', - }, - nav: [ - { text: 'Home', link: '/' }, - { text: 'Quick Start', link: '/users/quickstart' }, - { - text: 'Docs', - items: [ - { - text: 'User Docs', - items: [ - { text: 'Quickstart', link: '/users/quickstart' }, - { text: 'Installation Guide', link: '/users/installation' }, - { text: 'Build an Image', link: '/users/build-image' } - ] - }, - { - text: 'Technical Documentation', - items: [ - { text: 'Gardenlinux', link: '/projects/gardenlinux/' }, - { text: 'Builder', link: '/projects/builder/features' }, - { text: 'Python Gardenlinux Lib', link: '/projects/python-gardenlinux-lib/' }, - ] - }, - { - text: 'Contributing', link: '/contributing/', - } - ] - }, - ], - socialLinks: [ - { - icon: { - svg: '' - }, - link: 'https://x.com/GardenLinux' - }, - { - icon: { - svg: ' +Learn how to build Garden Linux images and packages for development and contribution purposes. + +## Building Images for Development + +For detailed instructions on building Garden Linux images, see the [Building Custom Flavors](/how-to/customization/building-flavors) guide, which covers: + +- Build requirements and prerequisites +- Basic and advanced build commands +- Cross-architecture builds +- Parallel build options +- Secure boot image generation + +## Building Packages + +Garden Linux packages are built using [the package-build scripts](https://github.com/gardenlinux/package-build). Understanding the package build system is essential for contributing package changes. + +### Package Repository Structure + +Each package has its own GitHub repository following the naming convention `package-{package_name}`. These packages are automatically picked up by [the workflows in the 'repo'](https://github.com/gardenlinux/repo). + +**Examples**: +- **Trivial example**: [`gardenlinux/package-containerd`](https://github.com/gardenlinux/package-containerd) +- **Non-trivial example**: [`gardenlinux/package-openssh`](https://github.com/gardenlinux/package-openssh) + +### Package Build Strategy + +Garden Linux follows a pragmatic approach to package management: + +**Default approach**: Use binary packages as provided by Debian +- Leverages Debian's extensive testing and security processes +- Reduces maintenance burden +- Ensures compatibility with Debian ecosystem + +**Rebuild only when necessary**: Create a `package-{package_name}` repository when: +- Garden Linux-specific patches are required +- Custom build environment is needed +- Package is temporarily unavailable in Debian testing + +### Types of Package Rebuilds + +#### 1. Source from Debian + +Rebuild Debian packages with Garden Linux modifications. + +**Use cases**: +- **Apply patches**: Add Garden Linux-specific patches on top of Debian source +- **Custom build environment**: Rebuild with specific compiler/runtime versions (e.g., newer golang, glibc, gcc) +- **Debian testing gaps**: Package temporarily removed from Debian testing (happens periodically) + +**Example workflow**: +```bash +# Clone package repository +git clone https://github.com/gardenlinux/package-openssh +cd package-openssh + +# Review Garden Linux patches +ls debian/patches/ + +# Build package +./build.sh +``` + +#### 2. Source from Upstream Project + +Package software directly from upstream when Debian doesn't provide suitable packages. + +**Use cases**: +- **Not in Debian**: Software not maintained by Debian +- **Version mismatch**: Debian maintains old version, newer upstream version required +- **Specialized needs**: Garden Linux requires features not in Debian package + +**Example**: +```bash +# Clone package repository +git clone https://github.com/gardenlinux/package-{upstream-software} +cd package-{upstream-software} + +# Check upstream source +cat debian/watch # Upstream version tracking + +# Build from upstream +./build.sh +``` + +#### 3. Native Source + +Package software developed and maintained by Garden Linux team. + +**Use cases**: +- **Garden Linux-specific tools**: Software developed by Garden Linux team +- **Integration components**: Tools for Garden Linux system integration +- **Custom utilities**: Garden Linux-specific system utilities + +**Example**: +```bash +# Clone native package +git clone https://github.com/gardenlinux/package-{native-tool} +cd package-{native-tool} + +# Source is maintained in repository +ls src/ + +# Build native package +./build.sh +``` + +## Package Development Workflow + +### Set Up Package Development Environment + +1. **Install build dependencies**: + ```bash + sudo apt install build-essential devscripts debhelper + ``` + +2. **Clone package repository**: + ```bash + git clone https://github.com/gardenlinux/package-{package_name} + cd package-{package_name} + ``` + +3. **Review package structure**: + ```bash + # Debian packaging files + ls debian/ + + # Build scripts + ls *.sh + + # Package-specific patches + ls debian/patches/ + ``` + +### Make Package Changes + +1. **Create feature branch**: + ```bash + git checkout -b feature/my-package-change + ``` + +2. **Modify source or patches**: + ```bash + # Add new patch + vim debian/patches/my-fix.patch + + # Update patch series + echo "my-fix.patch" >> debian/patches/series + ``` + +3. **Update changelog**: + ```bash + dch -i "Description of changes" + ``` + +4. **Test build locally**: + ```bash + ./build.sh + ``` + +### Submit Package Contributions + +1. **Commit changes**: + ```bash + git add debian/ + git commit -m "package: Add fix for issue XYZ" + ``` + +2. **Push and create PR**: + ```bash + git push origin feature/my-package-change + # Create pull request on GitHub + ``` + +3. **CI/CD validation**: + - Automated builds run on PR + - Package builds must succeed + - Tests must pass + +## Testing Package Changes + +### Local Testing + +Test your package changes before submitting: + +```bash +# Build package +./build.sh + +# Install locally in test environment +sudo dpkg -i ../package-name_version_arch.deb + +# Verify functionality +# ... test your changes ... + +# Remove test package +sudo apt remove package-name +``` + +### Integration Testing + +Test packages within Garden Linux image: + +```bash +# Build image with modified package +# (assuming package in local repo) +./build kvm-gardener_dev-amd64 + +# Test in QEMU +# ... verify package changes in running system ... +``` + +## Package Repository Automation + +The [`gardenlinux/repo`](https://github.com/gardenlinux/repo) repository contains workflows that: + +- Monitor package repositories for changes +- Trigger automated builds +- Publish packages to Garden Linux repository +- Maintain package metadata and dependencies + +**Package updates are automated**: +1. Changes merged to package repository +2. Workflow detects change +3. Package builds automatically +4. Published to Garden Linux APT repository +5. Available in next image builds + +## Best Practices + +### Package Maintenance + +- **Minimal changes**: Only rebuild when necessary +- **Document patches**: Clear commit messages and patch descriptions +- **Test thoroughly**: Build and test before submitting +- **Follow Debian policy**: Adhere to [Debian Policy](https://www.debian.org/doc/debian-policy/) +- **Version carefully**: Use appropriate version suffixes (e.g., `+gardenlinux1`) + +### Security Considerations + +- **Security patches**: Apply security fixes promptly +- **Upstream tracking**: Monitor upstream security advisories +- **Testing**: Verify security fixes don't introduce regressions +- **Documentation**: Document security-related changes clearly + +## Troubleshooting + +### Build Fails + +**Missing dependencies**: +```bash +# Install build dependencies +sudo apt build-dep package-name + +# Or install from debian/control +mk-build-deps -i debian/control +``` + +**Patch doesn't apply**: +```bash +# Refresh patches for new upstream version +quilt push -a +quilt refresh +``` + +### Package Won't Install + +**Dependency issues**: +```bash +# Check dependencies +dpkg-deb -I package-name.deb + +# Install with dependencies +sudo apt install -f ./package-name.deb +``` + +## Next Steps + +- **Test images**: [Testing an Image](/contributing/testing-image) +- **Contribution workflow**: [Contribution Workflow](/contributing/workflow) +- **Code style**: [Code Style Guide](/contributing/code-style) +- **Build flavors**: [Building Custom Flavors](/how-to/customization/building-flavors) + +## Related Documentation + +- **Explanation**: [Architecture](/explanation/architecture) - Build system design +- **Reference**: [Feature Glossary](/reference/feature-glossary) - Available features +- **How-to**: [Testing Custom Builds](/how-to/customization/testing-builds) - Testing procedures diff --git a/docs/contributing/workflow.md b/docs/contributing/workflow.md index b850381..3f0c7b8 100644 --- a/docs/contributing/workflow.md +++ b/docs/contributing/workflow.md @@ -1,5 +1,303 @@ +--- +title: "Contribution Workflow" +description: "Git workflow, GitHub workflows, and contribution process for Garden Linux" +category: "contributing" +tags: ["workflow", "git", "github", "ci-cd", "contribution"] +--- + # Contribution Workflow -Learn about the contribution workflow for Garden Linux. +Learn about the Git workflow, GitHub Actions pipelines, and contribution process for Garden Linux. + +## Git Workflow + +### Fork and Clone + +1. **Fork the repository**: + - Go to [github.com/gardenlinux/gardenlinux](https://github.com/gardenlinux/gardenlinux) + - Click "Fork" button + - Select your GitHub account + +2. **Clone your fork**: + ```bash + git clone https://github.com/YOUR-USERNAME/gardenlinux.git + cd gardenlinux + ``` + +3. **Add upstream remote**: + ```bash + git remote add upstream https://github.com/gardenlinux/gardenlinux.git + git fetch upstream + ``` + +### Create Feature Branch + +Create a branch for your changes: + +```bash +# Update main branch +git checkout main +git pull upstream main + +# Create feature branch +git checkout -b feature/my-improvement + +# Or for bug fixes +git checkout -b fix/issue-123 +``` + +**Branch naming conventions**: +- `feature/` - New features or enhancements +- `fix/` - Bug fixes +- `docs/` - Documentation changes +- `refactor/` - Code refactoring +- `test/` - Test additions or modifications + +### Make Changes + +1. **Make your changes**: + - Edit files + - Follow [Code Style](/contributing/code-style) guidelines + - Add tests if applicable + +2. **Test locally**: + ```bash + # Build image + ./build kvm-gardener_dev-amd64 + + # Run tests + make test + ``` + +3. **Commit changes**: + ```bash + git add . + git commit -m "feat: Add new feature XYZ" + ``` + +**Commit message format**: +``` +: + + + +