Skip to content

686f6c61/gitpins

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

33 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GitPins

Control the order of your GitHub repositories

Keep your best projects always visible on your GitHub profile

License: MIT TypeScript Next.js Tailwind CSS Prisma Deployment

Live Demo | Documentation | Self-Hosting


Screenshots

Landing Page

GitPins Landing

Dashboard

GitPins Dashboard

Configuration

GitPins Configuration

Admin Dashboard

GitPins Admin

Ban User

GitPins Ban

The Problem

GitHub sorts repositories by "last updated" date. This means your most important projects can get buried when you make a small fix to an old repo or create a new experimental project.

GitPins solves this by "touching" your chosen repositories (create/delete of a short-lived tag ref) in a controlled sequence, so GitHub's recency-based order matches your preferred top list.

Features

  • Drag & Drop Ordering - visually arrange your top list
  • Manual Sync - "Sync now" from the dashboard (CSRF-protected)
  • Scheduled Sync - trigger /api/sync from GitHub Actions or any scheduler you control
  • Smart Sync - skips when already ordered + touches only the minimal prefix needed
  • Single Strategy (Temporary Ref Touch) - no default-branch history noise, no file changes
  • Commit Cleanup (Optional) - removes GitPins commits (history rewrite; explicit warning)
  • Private Repos Support - include/exclude private repositories in the dashboard list
  • Bilingual UI - English and Spanish
  • Dark/Light Mode - theme toggle with system default
  • Privacy Controls - export your data and delete your account (requires reauth / sudo)
  • Admin Allowlist - admins are granted via admin_accounts (revocable)

How It Works

  1. Connect with GitHub (OAuth) - we create an app session cookie (JWT)
  2. Install the GitHub App - required so GitPins can create/delete temporary refs in selected repos
  3. Arrange your repos - save your desired top list and settings
  4. Sync
    • Manual: click "Sync now" in the dashboard
    • Scheduled: run GitHub Actions or any scheduler that calls POST /api/sync

Technical Details

GitPins updates the "last updated" timestamp by creating a temporary tag ref that points to HEAD, then deleting that tag immediately.

This keeps your default branch history clean (no [GitPins] commits in main/master).

Conceptually:

git rev-parse HEAD
git push origin HEAD:refs/tags/gitpins-touch-<id>
git push origin :refs/tags/gitpins-touch-<id>

See docs/ORDERING.md for the detailed algorithm, including the minimal-prefix optimization and what "single-pass" means in practice.

Security

GitPins is designed with security in mind:

  • Minimal GitHub App Permissions - only what is needed for temporary ref updates
  • No File Changes - GitPins creates and deletes temporary refs that point to the existing HEAD commit
  • Encrypted Tokens - Access tokens are encrypted with AES-256-GCM
  • Open Source - full code transparency

What GitPins CAN do:

  • Create/delete temporary refs in repos you installed the app on
  • Read repository metadata (name, stars, etc.) via the GitHub API
  • Optionally rewrite history to remove GitPins commits (cleanup feature; explicit confirmation)

What GitPins CANNOT do:

  • Delete repositories
  • Modify tracked files
  • Access other GitHub data (issues, PRs, etc.) unless you grant additional permissions

Cleanup warning: cleanup rewrites git history (force-updates the default branch). This can impact collaborators and forks. Treat it as a dangerous, opt-in operation.

Tech Stack

  • Framework: Next.js 16 (App Router)
  • Language: TypeScript 5
  • Database: PostgreSQL (via Prisma 7)
  • Auth: GitHub OAuth (GitHub Apps)
  • Styling: Tailwind CSS 4
  • Drag & Drop: dnd-kit
  • Deployment: Self-hosted Docker or Node.js + PostgreSQL

Documentation

Maintainer docs (recommended starting points):

  • docs/README.md - documentation index and suggested reading order
  • docs/LOCAL_DEV.md - Docker Compose local development setup
  • docs/ARCHITECTURE.md - system overview and flows
  • docs/SECURITY.md - threat model, auth, CSRF, admin, sync secret
  • docs/PRIVACY.md - export + deletion model
  • docs/ORDERING.md - ordering algorithm details
  • docs/DEPLOYMENT.md - generic self-hosted deployment checklist
  • docs/ADMIN.md - allowlist, sudo, audit model, bootstrap CLI
  • docs/API.md - maintainer API overview
  • docs/MIGRATIONS.md - Prisma migration notes for existing DBs
  • docs/TROUBLESHOOTING.md - common setup and runtime issues

Self-Hosting

Prerequisites

  • Node.js 22+ (recommended) or Docker
  • PostgreSQL database
  • GitHub App

Deployment Model

GitPins is portable and designed for self-hosting. A typical setup is:

  • a Docker-capable host or Node.js runtime
  • a PostgreSQL database
  • a public HTTPS domain
  • a GitHub App configured for that domain
  • an optional external scheduler for automatic sync

Compatible database options:

  • Self-hosted PostgreSQL
  • Managed PostgreSQL providers such as Supabase, Railway, Render, or any standard PostgreSQL host

1. Create a GitHub App

Go to GitHub Developer Settings and create a new app.

URLs Configuration

For Production:

Field Value
Homepage URL https://your-domain.com
Callback URL https://your-domain.com/api/auth/callback
Setup URL (optional) https://your-domain.com/api/auth/setup
Webhook URL Leave empty (not required)
Webhook Active ❌ Unchecked

For Local Development (Docker default):

Field Value
Homepage URL http://localhost:3001
Callback URL http://localhost:3001/api/auth/callback
Setup URL (optional) http://localhost:3001/api/auth/setup
Webhook URL Leave empty
Webhook Active ❌ Unchecked

If you run pnpm run dev directly (no Docker), use http://localhost:3000 instead of 3001.

Required Permissions

Configure these permissions in your GitHub App settings:

Repository Permissions:

Permission Access Level Purpose
Contents Read and write Create and delete temporary refs
Metadata Read-only Read repository list and info

Account Permissions:

Permission Access Level Purpose
Email addresses Read-only Get user email for identification

OAuth Settings

In the OAuth section of your GitHub App:

  • Request user authorization (OAuth) during installation: Enabled
  • Enable Device Flow: Optional

2. Clone and Install

git clone https://github.com/686f6c61/gitpins.git
cd gitpins
pnpm install --frozen-lockfile

3. Configure Environment

cp .env.example .env

Edit .env with your values:

DATABASE_URL="postgresql://..."
DIRECT_URL="postgresql://..."
GITHUB_APP_ID="your_app_id"
GITHUB_APP_CLIENT_ID="your_client_id"
GITHUB_APP_CLIENT_SECRET="your_client_secret"
GITHUB_APP_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----..."
NEXT_PUBLIC_APP_URL="https://your-domain.com"
JWT_SECRET="generate_with_openssl_rand_base64_32"
ENCRYPTION_SECRET="generate_with_openssl_rand_base64_32"

4. Setup Database

pnpm exec prisma db push

For incremental production updates on an existing database, review docs/MIGRATIONS.md.

5. Run

# Development
pnpm run dev

# Production
pnpm run build
pnpm start

Local Development Tips

When running locally with a dedicated GitHub App (gitpins-local):

  1. Use localhost app URLs:
    • Docker: http://localhost:3001
    • Non-Docker: http://localhost:3000
  2. Set environment variable: NEXT_PUBLIC_APP_URL=http://localhost:3001 (Docker) or http://localhost:3000 (non-Docker)
  3. Re-authenticate after changing app settings to refresh OAuth grants

Local Docker Setup (App + Postgres)

cp .env.docker.example .env.docker
docker compose up -d

If you already have PostgreSQL listening on localhost:5432, run Docker on another host port:

GITPINS_DB_PORT=5433 docker compose up -d

Services:

  • App: http://localhost:3001
  • Postgres: localhost:5432 by default, or localhost:5433 if GITPINS_DB_PORT=5433

By default, local Docker runs with:

  • GITPINS_DISABLE_GITHUB_MUTATIONS=true (safe mode: no GitHub write operations)

Required OAuth Scopes

When authenticating, GitPins requests these OAuth scopes:

  • repo - Access to private repositories (used by the dashboard repo list)
  • user:email - Access to email address

If you're experiencing "Resource not accessible by integration" errors, the user needs to re-authenticate to get a token with the correct scopes.

Scheduled Sync (GitHub Actions or Any Scheduler)

GitPins provides the sync endpoint (POST /api/sync) but does not run scheduled jobs by itself.

Any scheduler that can send an HTTP request will work. GitHub Actions is a common option because many GitHub users already have it available.

name: GitPins - Maintain Repo Order

on:
  schedule:
    - cron: '0 */6 * * *'
  workflow_dispatch:

jobs:
  sync:
    runs-on: ubuntu-latest
    steps:
      - name: Sync
        run: |
          curl -s -X POST "${{ vars.GITPINS_APP_URL }}/api/sync" \
            -H "X-GitPins-Sync-Secret: ${{ secrets.GITPINS_SYNC_SECRET }}"

You must set:

  1. GITPINS_SYNC_SECRET (repo secret): the per-user secret stored in repo_orders.syncSecret.
  2. GITPINS_APP_URL (repo variable): your app URL (for example https://your-domain.com).

Troubleshooting

Issue Solution
"Resource not accessible" Re-authenticate (logout/login) to refresh OAuth token
"Bad credentials" Check GITHUB_APP_PRIVATE_KEY format (include BEGIN/END lines)
Scheduled sync not running Check the scheduler logs. If you use GitHub Actions, inspect the workflow logs in the repo that hosts it
Repos not syncing Verify the GitHub App is installed on those repos

Deployment Model

GitPins ships as a normal Next.js app and can run anywhere you can provide:

  1. A Docker-capable host or platform
  2. A PostgreSQL database
  3. HTTPS with a stable canonical domain
  4. A GitHub App configured for that domain

See docs/DEPLOYMENT.md for the production checklist.

Admin Dashboard

GitPins includes an admin dashboard for managing users and viewing statistics.

Accessing the Admin Panel

  1. Grant admin access in the allowlist (admin_accounts table). Use pnpm run admin:access -- grant --github-id <id> or insert directly in DB.
  2. Log in with the granted account.
  3. Access the dashboard: Navigate to /admin after logging in with the admin account.

Admin Features

  • User Statistics: Total users, active users, banned users, sync counts
  • User Management: View all users with their saved setups and activity
  • Ban/Unban Users: Suspend users who violate terms of service
  • Delete Users: Remove users from the application (they can re-register)
  • Activity Charts: Visual graphs of registrations and syncs over 30 days

Security

The admin panel is protected by:

  • Session validation (must be logged in)
  • Database allowlist verification (admin_accounts, where revokedAt IS NULL)
  • All admin API endpoints return 403 Forbidden for non-admin users

Project Structure

src/
├── app/                   # Next.js App Router
│   ├── api/               # API Routes
│   │   ├── auth/          # OAuth endpoints
│   │   ├── repos/         # Repository management
│   │   └── sync/          # Sync endpoints (called manually or by an external scheduler)
│   ├── dashboard/         # Main dashboard
│   ├── admin/             # Admin panel
│   └── how-it-works/      # Documentation page
├── components/            # React components
├── lib/                   # Utility modules
│   ├── crypto.ts          # AES-256-GCM encryption
│   ├── session.ts         # JWT session management
│   ├── security.ts        # CSRF, rate limiting
│   ├── github.ts          # GitHub OAuth
│   └── github-app.ts      # GitHub App operations
├── i18n/                  # Internationalization
└── types/                 # TypeScript definitions

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/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

This project is licensed under the MIT License - see the LICENSE file for details.

Author

686f6c61 - @686f6c61


Made with code and mass energy by @686f6c61

If you find this useful, consider giving it a star!

About

Control the order of your GitHub repositories. Keep your best projects always visible.

Topics

Resources

License

Security policy

Stars

1 star

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages