diff --git a/.gitignore b/.gitignore
index 056dbb2..c07d5f6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,6 @@
!.gitignore
!github2forgejo
+!*.lock
!*.md
+!*.nix
diff --git a/README.md b/README.md
index 1a17f27..f42e06b 100644
--- a/README.md
+++ b/README.md
@@ -6,6 +6,41 @@ Plain simple, just install [Nushell](https://nushell.sh) and run the script:
./github2forgejo --help
```
+
+Help Output
+
+```
+Migrates a GitHub users repositories to a Forgejo instance.
+
+Accepted environment variables:
+
+ GITHUB_USER: The user to fetch the repositories from.
+ GITHUB_TOKEN: An access token for fetching private repositories. Optional.
+
+ FORGEJO_URL: The URL to the Forgejo instance. Must include the protocol (https://).
+ FORGEJO_USER: The user to migrate the repositories to.
+ FORGEJO_TOKEN: An access token for the specified user.
+
+ STRATEGY:
+ The strategy. Valid options are "mirrored" or "cloned" (case insensitive).
+ "mirrored" will mirror the repository and tell the Forgejo instance to
+ periodically update it, "cloned" will only clone once. "cloned" is
+ useful if you are never going to use GitHub again.
+
+ FORCE_SYNC:
+ Whether to delete a mirrored repo from the Forgejo instance if the
+ source on GitHub doesn't exist anymore. Must be either "true" or "false".
+
+To leave an environment variable unspecified, set it to an empty string.
+
+Usage:
+ > github2forgejo
+
+Flags:
+ -h, --help - Display the help message for this command
+```
+
+
You can either specify all the environment variables
for a uninteractive run, or run the script like so:
@@ -17,6 +52,69 @@ And get a nice interactive experience.
This works on any Forgejo instance.
+You can also set up a systemd service and timer to run every once in a while.
+
+Use the flake, like so:
+
+```nix
+{
+ inputs = {
+ nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
+
+ github2forgejo = {
+ url = "github:RGBCube/GitHub2Forgejo";
+
+ inputs.nixpkgs.follows = "nixpkgs";
+ };
+ };
+
+ outputs = { nixpkgs, github2forgejo, ... }: let inherit (nixpkgs) lib; in {
+ nixosConfigurations.myserver = lib.nixosSystem {
+ modules = [
+ github2forgejo.nixosModules.default
+
+ {
+ nixpkgs.overlays = [ github2forgejo.overlays.default ];
+
+ services.github2forgejo = {
+ enable = true;
+
+ # Something along the lines of:
+ #
+ # GITHUB_USER="RGBCube"
+ # GITHUB_TOKEN="ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ # FORGEJO_URL="https://git.rgbcu.be/"
+ # FORGEJO_USER="RGBCube"
+ # FORGEJO_TOKEN="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ # STRATEGY="mirrored"
+ # FORCE_SYNC="true"
+ #
+ # Do `GITHUB_TOKEN=""` if you want to only mirror public repositories of a person.
+ # You HAVE TO set each one of these. Leaving one unset will make the systemd unit fail!
+ environmentFile = "/secrets/github2forgejo.env";
+
+ # The default runs every day at midnight. But you can override it like so:
+ #
+ # timerConfig = {
+ # OnCalendar = "00:05";
+ # RandomizedDelaySec = "5h";
+ # Persistent = true;
+ # };
+ #
+ # Or you can disable the timer by setting `timerConfig` to null:
+ #
+ # timerConfig = null;
+ }
+ }
+ ];
+ }
+ };
+}
+```
+
+The script is also available as a package, you just need to use the
+`packages..default` or `packages..github2forgejo` outputs.
+
## FAQ
### What is the difference between mirroring and cloning?
diff --git a/flake.lock b/flake.lock
new file mode 100644
index 0000000..1383f19
--- /dev/null
+++ b/flake.lock
@@ -0,0 +1,43 @@
+{
+ "nodes": {
+ "nixpkgs": {
+ "locked": {
+ "lastModified": 1716715802,
+ "narHash": "sha256-usk0vE7VlxPX8jOavrtpOqphdfqEQpf9lgedlY/r66c=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "e2dd4e18cc1c7314e24154331bae07df76eb582f",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixpkgs-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "root": {
+ "inputs": {
+ "nixpkgs": "nixpkgs",
+ "systems": "systems"
+ }
+ },
+ "systems": {
+ "locked": {
+ "lastModified": 1681028828,
+ "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+ "owner": "nix-systems",
+ "repo": "default",
+ "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-systems",
+ "repo": "default",
+ "type": "github"
+ }
+ }
+ },
+ "root": "root",
+ "version": 7
+}
diff --git a/flake.nix b/flake.nix
new file mode 100644
index 0000000..7f8752c
--- /dev/null
+++ b/flake.nix
@@ -0,0 +1,115 @@
+{
+ description = "GitHub to Forgejo migration script";
+
+ inputs = {
+ nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
+
+ systems.url = "github:nix-systems/default";
+ };
+
+ outputs = { self, nixpkgs, systems }: let
+ inherit (nixpkgs) lib;
+
+ eachSystem = lib.genAttrs (import systems);
+ in {
+ packages = eachSystem (system: let pkgs = import nixpkgs { inherit system; }; in rec {
+ inherit (self.overlays.github2forgejo pkgs pkgs) github2forgejo;
+
+ default = github2forgejo;
+ });
+
+ overlays = rec {
+ default = github2forgejo;
+ github2forgejo = (final: super: {
+ github2forgejo = super.callPackage ./package.nix {};
+ });
+ };
+
+ nixosModules = rec {
+ default = github2forgejo;
+ github2forgejo = { config, utils, lib, pkgs, ... }: let
+ cfg = config.services.github2forgejo;
+ in {
+ options.services.github2forgejo = {
+ enable = lib.mkEnableOption (lib.mdDoc "the github2forgejo timer");
+ package = lib.mkPackageOption pkgs "github2forgejo" {};
+
+ environmentFile = lib.mkOption {
+ type = lib.types.path;
+ default = null;
+ description = lib.mdDoc ''
+ File containing environment variables required by GitHub2Forgejo,
+ in the format of an EnvironmentFile as described by {manpage}`systemd.exec(5)`.
+
+ You must set ALL of these environment variables:
+
+ GITHUB_USER: The user to fetch the repositories from.
+ GITHUB_TOKEN: An access token for fetching private repositories. Optional.
+
+ FORGEJO_URL: The URL to the Forgejo instance. Must include the protocol (https://).
+ FORGEJO_USER: The user to migrate the repositories to.
+ FORGEJO_TOKEN: An access token for the specified user.
+
+ STRATEGY:
+ The strategy. Valid options are "mirrored" or "cloned" (case insensitive).
+ "mirrored" will mirror the repository and tell the Forgejo instance to
+ periodically update it, "cloned" will only clone once. "cloned" is
+ useful if you are never going to use GitHub again.
+
+ FORCE_SYNC:
+ Whether to delete a mirrored repo from the Forgejo instance if the
+ source on GitHub doesn't exist anymore. Must be either "true" or "false".
+
+ You must set an environment variable to an empty string to leave it "unset".
+ '';
+
+ example = "/secrets/github2forgejo.env";
+ };
+
+ timerConfig = lib.mkOption {
+ type = with lib.types; nullOr (attrsOf utils.systemdUtils.unitOptions.unitOption);
+ default = {
+ OnCalendar = "daily";
+ Persistent = true;
+ };
+
+ description = lib.mdDoc ''
+ When to run the script. See {manpage}`systemd.timer(5)` for
+ details. If null, no timer will be created and the script
+ will only run when explicitly started.
+ '';
+
+ example = {
+ OnCalendar = "00:05";
+ RandomizedDelaySec = "5h";
+ Persistent = true;
+ };
+ };
+ };
+
+ config = lib.mkIf cfg.enable {
+ systemd.services.github2forgejo = {
+ wants = [ "network-online.target" ];
+ after = [ "network-online.target" ];
+ restartIfChanged = false;
+
+ serviceConfig = {
+ Type = "oneshot";
+ ExecStart = lib.getExe cfg.package;
+
+ User = "github2forgejo";
+ DynamicUser = true;
+
+ EnvironmentFile = cfg.environmentFile;
+ };
+ };
+
+ systemd.timers.github2forgejo = lib.mkIf (cfg.timerConfig != null) {
+ wantedBy = [ "timers.target" ];
+ timerConfig = cfg.timerConfig;
+ };
+ };
+ };
+ };
+ };
+}
diff --git a/package.nix b/package.nix
new file mode 100644
index 0000000..128ec13
--- /dev/null
+++ b/package.nix
@@ -0,0 +1,43 @@
+{
+ lib,
+ stdenvNoCC,
+
+ nushell,
+}:
+
+stdenvNoCC.mkDerivation {
+ name = "github2forgejo";
+ version = "master";
+
+ src = ./.;
+
+ dontBuild = true;
+ dontConfigure = true;
+
+ nativeBuildInputs = [ nushell ];
+
+ installPhase = ''
+ runHook preInstall
+
+ mkdir -p $out/bin
+ cp github2forgejo $out/bin
+
+ runHook postInstall
+ '';
+
+ fixupPhase = ''
+ runHook preFixup
+
+ substituteInPlace $out/bin/github2forgejo \
+ --replace '/usr/bin/env nu' '${nushell}/bin/nu'
+
+ runHook postFixup
+ '';
+
+ meta = with lib; {
+ description = "GitHub to Forgejo migration script";
+ homepage = "https://git.rgbcu.be/RGBCube/GitHub2Forgejo";
+ license = licenses.gpl3Only;
+ maintainers = with maintainers; [ RGBCube ];
+ };
+}