Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Copilot Instructions

This repository follows the DPC (Dans Plugins Community) conventions defined at
https://github.com/Dans-Plugins/dpc-conventions. Read those conventions before
making any changes.

## Technology Stack

- Language: Java 17
- Build tool: Maven
- Framework: Spring Boot 3
- Key libraries: kohsuke/github-api, Eclipse JGit
- Test framework: JUnit 5 (via Spring Boot Test)

## Project Structure

- `src/main/java/com/github/backup/` – Core application classes (backup service, GitHub service, CLI runner)
- `src/main/java/com/github/backup/web/` – Spring MVC REST controller and request/response models for web mode
- `src/main/resources/` – `application.properties`, `application-web.properties`, and static web assets
- `src/test/java/` – Unit tests mirroring the main source tree

## Coding Conventions

- Follow the existing package structure (`com.github.backup`) when adding new classes.
- Configuration is loaded from `application.properties`; use `@Value` or `@ConfigurationProperties` for new options.
- All new configuration options must be documented in `CONFIG.md`.
- User-facing documentation changes must be included in the same pull request as the related code change.

## Contribution Workflow

- Branch from `develop` for all changes.
- Open a pull request against `develop`, not `main`.
- Reference the related GitHub issue in every pull request description.
25 changes: 25 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Build

on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]

jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read

steps:
- uses: actions/checkout@v4

- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'

- name: Build with Maven
run: mvn clean verify
29 changes: 29 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Release

on:
release:
types: [ created ]

permissions:
contents: write

jobs:
build-and-attach:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'

- name: Build with Maven
run: mvn clean package

- name: Upload JAR to release
uses: softprops/action-gh-release@v2
with:
files: target/gh-backup-*.jar
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## [Unreleased]

## [1.0.0] – 2026-01-01

### Added

- CLI mode: back up public repositories for one or more GitHub users or organizations by passing their names as arguments
- Interactive mode (`-i` flag): prompt-based interface with `backup`, `status`, and `exit` commands
- Web UI mode (`-Dspring.profiles.active=web`): browser-based interface for managing backups
- REST API endpoints (`POST /api/backup`, `GET /api/status`) for programmatic access
- GitHub authentication via `GITHUB_TOKEN` environment variable for higher API rate limits
- Configurable backup directory via `backup.directory` system property (defaults to `~/gh-backups/`)
- Cross-platform path normalization (Linux, macOS, Windows)
- Parallel backup of multiple users and organizations
- Incremental updates: existing repositories are updated with `git fetch` instead of re-cloned
117 changes: 117 additions & 0 deletions COMMANDS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# Commands Reference

gh-backup is invoked from the command line via the built JAR. This document lists all supported arguments and modes.

## Basic Syntax

```
java [JVM_OPTIONS] -jar target/gh-backup-1.0.0.jar [OPTIONS] [USER/ORG...]
```

## Positional Arguments

### `<user/org> [user/org2] ...`

**Description:** One or more GitHub usernames or organization names whose public repositories should be backed up.
**Required:** Yes (unless using interactive mode or web mode)
**Example:**
```bash
java -jar target/gh-backup-1.0.0.jar octocat github spring-projects
```

## Options

### `-i` – Interactive Mode

**Description:** Start the tool in interactive mode, providing a prompt for issuing commands without restarting the application.
**Usage:**
```bash
java -jar target/gh-backup-1.0.0.jar -i
```

### Interactive Mode Commands

Once in interactive mode, the following commands are available at the `>` prompt:

| Command | Description |
|---------|-------------|
| `backup <user/org>` | Back up all public repositories for the given GitHub user or organization |
| `status` | Display the backup directory path and a summary of all backed-up repositories |
| `exit` | Exit interactive mode and terminate the application |

## JVM System Properties

These are passed with `-D` before the `-jar` flag.

### `-Dbackup.directory=<path>`

**Description:** Override the directory where repositories are saved.
**Default:** `~/gh-backups/` (the `gh-backups` folder in the current user's home directory)
**Example:**
```bash
java -Dbackup.directory=/mnt/storage/github-backups -jar target/gh-backup-1.0.0.jar octocat
```

### `-Dspring.profiles.active=web`

**Description:** Start the application as a web server instead of a CLI tool.
**Default:** CLI mode
**Example:**
```bash
java -Dspring.profiles.active=web -jar target/gh-backup-1.0.0.jar
```

### `-Dserver.port=<port>`

**Description:** Set the HTTP port for the web server (only effective in web mode).
**Default:** `8080`
**Example:**
```bash
java -Dspring.profiles.active=web -Dserver.port=9000 -jar target/gh-backup-1.0.0.jar
```

## Environment Variables

### `GITHUB_TOKEN`

**Description:** A GitHub personal access token used to authenticate API requests. Increases the API rate limit from 60 to 5,000 requests per hour.
**Required:** No
**Example:**
```bash
export GITHUB_TOKEN=ghp_yourTokenHere
java -jar target/gh-backup-1.0.0.jar octocat
```

## Web API Endpoints

When running in web mode (`-Dspring.profiles.active=web`), the following REST endpoints are available:

| Method | Path | Description |
|--------|------|-------------|
| `POST` | `/api/backup` | Start a backup for a given user or organization |
| `GET` | `/api/status` | Return backup status and a list of all backed-up repositories |

### POST /api/backup

**Request body:**
```json
{ "username": "octocat" }
```

**Response:**
```json
{ "message": "Backup completed for octocat", "repositoryCount": 8 }
```

### GET /api/status

**Response:**
```json
{
"backupDirectory": "/home/user/gh-backups",
"users": ["octocat"],
"repositories": [
{ "name": "Hello-World", "owner": "octocat", "lastUpdated": "2026-01-10T12:30:45" }
]
}
```
85 changes: 85 additions & 0 deletions CONFIG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Configuration Guide

Configuration is provided through Spring Boot property files and JVM system properties.

The main configuration file is `src/main/resources/application.properties`. Values can be overridden at runtime with `-D<property>=<value>`.

---

## backup.directory

**Type:** string (file path)
**Default:** `${user.home}/gh-backups`
**Description:** The directory where cloned repositories are stored. The path is resolved relative to the user's home directory by default and is normalized for cross-platform compatibility (Linux, macOS, Windows).

**Override at runtime:**
```bash
java -Dbackup.directory=/mnt/storage/github-backups -jar target/gh-backup-1.0.0.jar octocat
```

Windows example:
```bat
java -Dbackup.directory=C:\Backups\GitHub -jar target/gh-backup-1.0.0.jar octocat
```

---

## backup.mode

**Type:** string (`cli` | `web`)
**Default:** `cli`
**Description:** Controls whether the application runs as a command-line tool (`cli`) or as a web server (`web`). Use `web` by activating the `web` Spring profile.

**Override at runtime:**
```bash
java -Dspring.profiles.active=web -jar target/gh-backup-1.0.0.jar
```

The `web` profile (`application-web.properties`) automatically sets `backup.mode=web` and enables the servlet web application type.

---

## spring.main.web-application-type

**Type:** string (`none` | `servlet`)
**Default:** `none` (CLI mode)
**Description:** Spring Boot property that controls whether an embedded web server is started. Set to `servlet` when using web mode. Managed automatically by the `web` Spring profile.

---

## server.port

**Type:** integer
**Default:** `8080`
**Description:** The HTTP port on which the web server listens. Only effective when running in web mode.

**Override at runtime:**
```bash
java -Dspring.profiles.active=web -Dserver.port=9000 -jar target/gh-backup-1.0.0.jar
```

---

## logging.level.com.github.backup

**Type:** string (log level)
**Default:** `INFO`
**Description:** Log level for application classes. Increase to `DEBUG` for verbose output during troubleshooting.

**Override at runtime:**
```bash
java -Dlogging.level.com.github.backup=DEBUG -jar target/gh-backup-1.0.0.jar octocat
```

---

## GITHUB_TOKEN (environment variable)

**Type:** string
**Default:** not set
**Description:** A GitHub personal access token used to authenticate GitHub API requests. When set, the rate limit increases from 60 to 5,000 requests per hour. Not set via `application.properties`; pass it as an environment variable.

```bash
export GITHUB_TOKEN=ghp_yourTokenHere
java -jar target/gh-backup-1.0.0.jar octocat
```
74 changes: 74 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Contributing

## Thank You

Thank you for your interest in contributing to gh-backup! This guide will help you get started.

## Links

- [Website](https://dansplugins.com)
- [Discord](https://discord.gg/xXtuAQ2)

## Requirements

- A GitHub account
- Git installed on your local machine
- Java 17 or higher
- Maven 3.6 or higher
- A Java IDE or text editor

## Getting Started

1. [Sign up for GitHub](https://github.com/signup) if you don't have an account.
2. Fork the repository by clicking **Fork** at the top right of the repo page.
3. Clone your fork:
```bash
git clone https://github.com/<your-username>/gh-backup.git
```
4. Open the project in your IDE.
5. Build the project:
```bash
mvn clean package
```
If you encounter errors, please open an issue.

## Identifying What to Work On

### Issues

Work items are tracked as [GitHub issues](https://github.com/dmccoystephenson/gh-backup/issues).

### Milestones

Issues are grouped into [milestones](https://github.com/dmccoystephenson/gh-backup/milestones) representing upcoming releases.

## Making Changes

1. Make sure an issue exists for the work. If not, create one.
2. Switch to the `develop` branch: `git checkout develop`
3. Create a feature branch: `git checkout -b <descriptive-branch-name>`
4. Make your changes.
5. Test your changes (see [Testing](#testing)).
6. Commit: `git commit -m "Brief description of changes"`
7. Push to your fork: `git push origin <branch-name>`
8. Open a pull request against the `develop` branch of the upstream repository. Include a description and link the related issue using `#<number>`.
9. Address any review feedback.
10. Once approved, the maintainer will merge the PR into `develop`.

## Testing

Run the unit tests with:

Linux / macOS:
```bash
mvn clean test
```

Windows:
```bat
mvn clean test
```

## Questions

Ask in the [Discord server](https://discord.gg/xXtuAQ2).
Loading