From 90c83b4694150bdcfe4fcac1c55fcfdef17c3612 Mon Sep 17 00:00:00 2001 From: seth Date: Fri, 26 Jan 2024 05:43:47 -0500 Subject: initial commit --- .github/dependabot.yml | 8 +++ .github/workflows/ci.yaml | 26 ++++++++ .github/workflows/flakehub-publish.yaml | 27 +++++++++ .github/workflows/update-lock.yaml | 60 +++++++++++++++++++ LICENSE | 21 +++++++ README.md | 102 ++++++++++++++++++++++++++++++++ default.nix | 37 ++++++++++++ flake.lock | 27 +++++++++ flake.nix | 29 +++++++++ module.nix | 72 ++++++++++++++++++++++ test/flake.lock | 64 ++++++++++++++++++++ test/flake.nix | 55 +++++++++++++++++ 12 files changed, 528 insertions(+) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/ci.yaml create mode 100644 .github/workflows/flakehub-publish.yaml create mode 100644 .github/workflows/update-lock.yaml create mode 100644 LICENSE create mode 100644 README.md create mode 100644 default.nix create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 module.nix create mode 100644 test/flake.lock create mode 100644 test/flake.nix diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..1d662ce --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,8 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "weekly" + commit-message: + prefix: "actions" diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..6d530a9 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,26 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + workflow_dispatch: + +jobs: + test-module: + name: Test module + runs-on: ubuntu-latest + container: nixos/nix:sha256:b8ea88f763f33dfda2317b55eeda3b1a4006692ee29e60ee54ccf6d07348c598 # 2.19.3 + + permissions: + contents: read + + steps: + - name: Checkout repository + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + + - name: Run test script + run: | + set -eux + + nix develop ./test --command 'run-ci' diff --git a/.github/workflows/flakehub-publish.yaml b/.github/workflows/flakehub-publish.yaml new file mode 100644 index 0000000..f707375 --- /dev/null +++ b/.github/workflows/flakehub-publish.yaml @@ -0,0 +1,27 @@ +name: Publish on Flakehub + +on: + push: + branches: [main] + tags: + - "v*.*.*" + +jobs: + publish: + name: Publish + runs-on: ubuntu-latest + container: nixos/nix:sha256:b8ea88f763f33dfda2317b55eeda3b1a4006692ee29e60ee54ccf6d07348c598 # 2.19.3 + + permissions: + contents: read + id-token: write + + steps: + - name: Checkout repository + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + + - name: Push to Flakehub + uses: DeterminateSystems/flakehub-push@b441737e7d01e044d7b60a3240fb81cbf827bee0 # v3 + with: + visibility: "public" + rolling: ${{ !startsWith(github.ref, 'refs/tags/v' )}} diff --git a/.github/workflows/update-lock.yaml b/.github/workflows/update-lock.yaml new file mode 100644 index 0000000..9a3628f --- /dev/null +++ b/.github/workflows/update-lock.yaml @@ -0,0 +1,60 @@ +name: Update flake.lock + +on: + schedule: + # run every saturday + - cron: "0 0 * * 6" + workflow_dispatch: + +jobs: + update: + name: Update + runs-on: ubuntu-latest + container: nixos/nix:sha256:b8ea88f763f33dfda2317b55eeda3b1a4006692ee29e60ee54ccf6d07348c598 # 2.19.3 + + permissions: + contents: write + pull-requests: write + + steps: + - name: Checkout repository + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + + - name: Create new branch + id: branch + run: | + branch="update-flake-lock" + + echo "branch=$branch" >> "$GITHUB_OUTPUT" + git switch -c "$branch" + + - name: Update flake inputs + run: | + nix flake update \ + --commit-lock-file \ + --commit-lockfile-summary "chore: update flake inputs" + + - name: Update test flake inputs + run: | + pushd ./dev + + nix flake update \ + --commit-lock-file \ + --commit-lockfile-summary "chore: update test flake inputs" + + popd + + - name: Make PR if needed + env: + GH_TOKEN: ${{ github.token }} + BRANCH: ${{ steps.branch.outputs.branch }} + run: | + if ! git diff --color=always --exit-code origin/main; then + git push -u origin "$BRANCH" + + gh pr create \ + --base main \ + --head "$BRANCH" \ + --title "chore: update flake inputs" \ + --fill + fi diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..4a1e9b2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 seth + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..8d1fc45 --- /dev/null +++ b/README.md @@ -0,0 +1,102 @@ +# procfile-nix + +A library + [flake-parts](https://flake.parts/) module that helps you manage procfiles and background jobs with [overmind](https://github.com/DarthSim/overmind)! + +## Usage + +Regardless of if you use the library or flakeModule, you will be putting a package into your development shells. +Following this, the name you gave the Procfile will be avalible as a command while will setup all of your processes. + +Example: + +```shell +$ nix develop +$ myprocfile +``` + +You can also send the command to run in the background like so: `myprocfile &` + +## Usage (library) + +First, put this in your `flake.nix`: + +```nix +{ + inputs = { + nixpkgs.url = "nixpkgs/nixpkgs-unstable"; + procfile-nix = { + url = "github:getchoo/procfile-nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = { nixpkgs, procfile-nix, ... }: let + systems = [ "x86_64-linux" "aarch64-linux" ]; + + forAllSystems = f: nixpkgs.lib.genAttrs systems (system: f nixpkgs.legacyPackages.${system}); + in { + devShells = forAllSystems ({ + lib, + pkgs, + system, + ... + }: let + procfile = procfile-nix.lib.${system}.mkProcfileRunner { + name = "daemons"; + procGroup = { + redis = lib.getExe' pkgs.redis "redis-server"; + }; + }; + in { + default = pkgs.mkShell { + packages = [ procfile ]; + }; + }); + }; +} +``` + +Then run `nix develop`, `daemons &`, and you're good to go! + +## Usage (flakeModule) + +```nix +{ + + inputs = { + nixpkgs.url = "nixpkgs/nixpkgs-unstable"; + flake-parts = { + url = "github:hercules-ci/flake-parts"; + inputs.nixpkgs-lib.follows = "nixpkgs"; + }; + procfile-nix = { + url = "github:getchoo/procfile-nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = inputs: + inputs.flake-parts.lib.mkFlake { inherit inputs; } { + systems = [ "x86_64-linux" "aarch64-linux" ]; + + imports = [ inputs.procfile-nix.flakeModule ]; + + perSystem = { + config, + lib, + pkgs, + ... + }: { + procfiles.daemons.processes = { + redis = lib.getExe' pkgs.redis "redis-server"; + }; + + devShells.default = pkgs.mkShell { + packages = [ config.procfiles.daemons.package ]; + }; + }; + }; +} +``` + +Similar to the last example, `nix develop` and `daemons &` may be run to start your Procfile diff --git a/default.nix b/default.nix new file mode 100644 index 0000000..ad898a9 --- /dev/null +++ b/default.nix @@ -0,0 +1,37 @@ +let + lock = builtins.fromJSON (builtins.readFile ./flake.lock); + nixpkgs' = fetchTarball { + url = lock.nodes.nixpkgs.locked.url or "https://github.com/NixOS/nixpkgs/archive/${lock.nodes.nixpkgs.locked.rev}.tar.gz"; + sha256 = lock.nodes.nixpkgs.locked.narHash; + }; +in + { + nixpkgs ? + import nixpkgs' { + config = {}; + overlays = []; + inherit system; + }, + system ? builtins.currentSystem, + }: let + pkgs = nixpkgs; + inherit (nixpkgs) lib; + + toProcfile = procGroup: + lib.concatLines ( + lib.mapAttrsToList (name: cmd: "${name}: ${cmd}") procGroup + ); + in { + mkProcfileRunner = { + name, + procGroup, + }: + pkgs.writeShellApplication { + inherit name; + runtimeInputs = [pkgs.overmind]; + text = '' + set -x + overmind start -f ${pkgs.writeText name (toProcfile procGroup)} --root "$PWD" "$@" + ''; + }; + } diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..21a40b6 --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1706173671, + "narHash": "sha256-lciR7kQUK2FCAYuszyd7zyRRmTaXVeoZsCyK6QFpGdk=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "4fddc9be4eaf195d631333908f2a454b03628ee5", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..9c9dd13 --- /dev/null +++ b/flake.nix @@ -0,0 +1,29 @@ +{ + description = "Procfile generation in your Nix shells!"; + + inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + + outputs = { + self, + nixpkgs, + }: let + systems = [ + "x86_64-linux" + "aarch64-linux" + "x86_64-darwin" + "aarch64-darwin" + ]; + + forAllSystems = f: nixpkgs.lib.genAttrs systems (system: f nixpkgs.legacyPackages.${system}); + in { + lib = forAllSystems (pkgs: + import ./. { + nixpkgs = pkgs; + inherit (pkgs) system; + }); + + flakeModule = import ./module.nix self; + + formatter = forAllSystems (pkgs: pkgs.alejandra); + }; +} diff --git a/module.nix b/module.nix new file mode 100644 index 0000000..cf243f9 --- /dev/null +++ b/module.nix @@ -0,0 +1,72 @@ +self: { + lib, + flake-parts-lib, + ... +}: let + inherit + (flake-parts-lib) + mkPerSystemOption + ; + + inherit + (lib) + literalExpression + mdDoc + mkOption + types + ; + + procfileSubmodule = { + config, + name, + system, + ... + }: { + options = { + processes = mkOption { + type = types.attrsOf types.str; + default = {}; + description = mdDoc "Attribute set mapping the names of processes to their command"; + example = literalExpression '' + { + redis = lib.getExe' pkgs.redis "redis-server"; + } + ''; + }; + + package = mkOption { + type = types.package; + description = mdDoc "Final package containing runner for Procfile"; + readOnly = true; + }; + }; + + config = { + package = self.lib.${system}.mkProcfileRunner { + inherit name; + procGroup = config.processes; + }; + }; + }; +in { + options = { + perSystem = mkPerSystemOption ({system, ...}: { + options.procfiles = mkOption { + type = types.attrsOf (types.submoduleWith { + modules = [procfileSubmodule]; + specialArgs = {inherit system;}; + }); + + default = {}; + description = mdDoc "Attribute set containing procfile declarations"; + example = literalExpression '' + { + daemons.processes = { + redis = lib.getExe' pkgs.redis "redis-server"; + }; + } + ''; + }; + }); + }; +} diff --git a/test/flake.lock b/test/flake.lock new file mode 100644 index 0000000..cd4bda2 --- /dev/null +++ b/test/flake.lock @@ -0,0 +1,64 @@ +{ + "nodes": { + "call-flake": { + "locked": { + "lastModified": 1705800408, + "narHash": "sha256-bmhE1TmrJG4ba93l9WQTLuYM53kwGQAjYHRvHOeuxWU=", + "owner": "divnix", + "repo": "call-flake", + "rev": "d3327852c5de242e340cb0fd798807c5258e28cc", + "type": "github" + }, + "original": { + "owner": "divnix", + "repo": "call-flake", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1706173671, + "narHash": "sha256-lciR7kQUK2FCAYuszyd7zyRRmTaXVeoZsCyK6QFpGdk=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "4fddc9be4eaf195d631333908f2a454b03628ee5", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "parts": { + "inputs": { + "nixpkgs-lib": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1704982712, + "narHash": "sha256-2Ptt+9h8dczgle2Oo6z5ni5rt/uLMG47UFTR1ry/wgg=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "07f6395285469419cf9d078f59b5b49993198c00", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "root": { + "inputs": { + "call-flake": "call-flake", + "nixpkgs": "nixpkgs", + "parts": "parts" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/test/flake.nix b/test/flake.nix new file mode 100644 index 0000000..bb8ff4c --- /dev/null +++ b/test/flake.nix @@ -0,0 +1,55 @@ +{ + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + + parts = { + url = "github:hercules-ci/flake-parts"; + inputs.nixpkgs-lib.follows = "nixpkgs"; + }; + + call-flake.url = "github:divnix/call-flake"; + }; + + outputs = inputs: + inputs.parts.lib.mkFlake {inherit inputs;} { + systems = [ + "x86_64-linux" + "aarch64-linux" + ]; + + imports = [(inputs.call-flake ../.).flakeModule]; + + debug = true; + + perSystem = { + config, + lib, + pkgs, + ... + }: { + procfiles.daemons.processes = { + redis = lib.getExe' pkgs.redis "redis-server"; + }; + + devShells.default = pkgs.mkShellNoCC { + packages = [ + (pkgs.writeShellScriptBin "run-ci" '' + set -x + + exec ${lib.getExe config.procfiles.daemons.package} & + sleep 5 # avoid race conditions + + if ! overmind status | grep running; then + echo "Processes failed to launch! Exiting with error" + overmind kill + exit 1 + fi + + overmind kill + echo "Process finished! Exiting as success" + '') + ]; + }; + }; + }; +} -- cgit v1.2.3