From b404d0fc8e304284d7fc8c16e1c5c517b0d4e970 Mon Sep 17 00:00:00 2001 From: RGBCube Date: Wed, 29 May 2024 10:01:10 +0300 Subject: [PATCH 1/8] Add package.nix --- .gitignore | 1 + package.nix | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 package.nix diff --git a/.gitignore b/.gitignore index 056dbb2..e0cc3c7 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ !github2forgejo !*.md +!*.nix 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 ]; + }; +} From 26e8fe7f5d967c7b39b9b08516aed00317c2cf7a Mon Sep 17 00:00:00 2001 From: RGBCube Date: Wed, 29 May 2024 10:30:14 +0300 Subject: [PATCH 2/8] Add flake --- .gitignore | 1 + flake.lock | 43 +++++++++++++++++++++ flake.nix | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 155 insertions(+) create mode 100644 flake.lock create mode 100644 flake.nix diff --git a/.gitignore b/.gitignore index e0cc3c7..c07d5f6 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,6 @@ !.gitignore !github2forgejo +!*.lock !*.md !*.nix 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..400b724 --- /dev/null +++ b/flake.nix @@ -0,0 +1,111 @@ +{ + 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 { + default = github2forgejo; + github2forgejo = pkgs.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 github2gitea 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 { + nixpkgs.overlays = [(final: super: { + github2forgejo = super.callPackage ./package.nix {}; + })]; + + systemd.services.github2forgeo = { + wants = [ "network-online.target" ]; + after = [ "network-online.target" ]; + restartIfChanged = false; + + serviceConfig = { + Type = "oneshot"; + ExecStart = toString cfg.package; + + User = "github2forgejo"; + DynamicUser = true; + + EnvironmentFile = cfg.environmentFile; + }; + }; + + systemd.timers.github2forgejo = lib.mkIf (cfg.timerConfig != null) { + wantedBy = [ "timers.target" ]; + timerConfig = cfg.timerConfig; + }; + }; + }; + }; + }; +} From 3b9dacc0835cd7470c9df5b6c6a75186603d9f83 Mon Sep 17 00:00:00 2001 From: RGBCube Date: Wed, 29 May 2024 10:33:20 +0300 Subject: [PATCH 3/8] Add overlay and remove overlay usage from module --- flake.nix | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/flake.nix b/flake.nix index 400b724..cff6fac 100644 --- a/flake.nix +++ b/flake.nix @@ -13,10 +13,18 @@ eachSystem = lib.genAttrs (import systems); in { packages = eachSystem (system: let pkgs = import nixpkgs { inherit system; }; in rec { - default = github2forgejo; - github2forgejo = pkgs.callPackage ./package.nix {}; + 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 @@ -24,7 +32,7 @@ in { options.services.github2forgejo = { enable = lib.mkEnableOption (lib.mdDoc "the github2gitea timer"); - package = lib.mkPackageOption pkgs "github2forgejo"; + package = lib.mkPackageOption pkgs "github2forgejo" {}; environmentFile = lib.mkOption { type = lib.types.path; @@ -80,10 +88,6 @@ }; config = lib.mkIf cfg.enable { - nixpkgs.overlays = [(final: super: { - github2forgejo = super.callPackage ./package.nix {}; - })]; - systemd.services.github2forgeo = { wants = [ "network-online.target" ]; after = [ "network-online.target" ]; From d8d002d4881812091a15819626205c4175e474b0 Mon Sep 17 00:00:00 2001 From: RGBCube Date: Wed, 29 May 2024 10:42:04 +0300 Subject: [PATCH 4/8] NOT GITEA --- flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index cff6fac..bfd1c95 100644 --- a/flake.nix +++ b/flake.nix @@ -31,7 +31,7 @@ cfg = config.services.github2forgejo; in { options.services.github2forgejo = { - enable = lib.mkEnableOption (lib.mdDoc "the github2gitea timer"); + enable = lib.mkEnableOption (lib.mdDoc "the github2forgejo timer"); package = lib.mkPackageOption pkgs "github2forgejo" {}; environmentFile = lib.mkOption { From 2bb63f468e8aa7e1bd99dd96ed925db9f14ab55c Mon Sep 17 00:00:00 2001 From: RGBCube Date: Wed, 29 May 2024 10:44:34 +0300 Subject: [PATCH 5/8] Fix typo --- flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index bfd1c95..3a02cb8 100644 --- a/flake.nix +++ b/flake.nix @@ -88,7 +88,7 @@ }; config = lib.mkIf cfg.enable { - systemd.services.github2forgeo = { + systemd.services.github2forgejo = { wants = [ "network-online.target" ]; after = [ "network-online.target" ]; restartIfChanged = false; From 0d99ad2dca2a2c3f78a4ae50e9af5a0748c76cac Mon Sep 17 00:00:00 2001 From: RGBCube Date: Wed, 29 May 2024 11:40:23 +0300 Subject: [PATCH 6/8] Fix systemd service --- flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index 3a02cb8..7f8752c 100644 --- a/flake.nix +++ b/flake.nix @@ -95,7 +95,7 @@ serviceConfig = { Type = "oneshot"; - ExecStart = toString cfg.package; + ExecStart = lib.getExe cfg.package; User = "github2forgejo"; DynamicUser = true; From a2f91c4bf75f99da013a5a682a7fe323de306507 Mon Sep 17 00:00:00 2001 From: RGBCube Date: Wed, 29 May 2024 11:56:42 +0300 Subject: [PATCH 7/8] Add flake example in README --- README.md | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/README.md b/README.md index 1a17f27..3fe670b 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,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? From 0cb9aac71bb22f8058d1db8eb3ba62e83f5641bf Mon Sep 17 00:00:00 2001 From: RGBCube Date: Wed, 29 May 2024 11:57:55 +0300 Subject: [PATCH 8/8] Add help output to README --- README.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/README.md b/README.md index 3fe670b..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: