diff --git a/.github/workflows/image.yml b/.github/workflows/image.yml new file mode 100644 index 0000000..a008fb7 --- /dev/null +++ b/.github/workflows/image.yml @@ -0,0 +1,25 @@ +name: Publish Docker Image + +on: + push: + tags: + - '**[0-9]+.[0-9]+.[0-9]+*' + +jobs: + build: + runs-on: ubuntu-24.04 + + permissions: + contents: read + id-token: write + + env: + ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }} + + steps: + - uses: actions/checkout@v4 + - uses: DeterminateSystems/nix-installer-action@main + - uses: DeterminateSystems/magic-nix-cache-action@main + + - name: Deploy Docker Image + run: nix run .#deploy diff --git a/flake.nix b/flake.nix index fe7294c..49251c2 100644 --- a/flake.nix +++ b/flake.nix @@ -60,6 +60,56 @@ } ); + packages = forAllSystems ( + pkgs: + let + postgresql = pkgs.postgresql.dev; + cargo-pgrx = import ./nix/pgrx.nix { inherit pkgs; }; + + pname = "pglite-fusion"; + version = "0.0.0"; + + postgres = pkgs.dockerTools.pullImage { + imageName = "postgres"; + imageDigest = "sha256:026d0ab72b34310b68160ab9299aa1add5544e4dc3243456b94f83cb1c119c2c"; + sha256 = "sha256-Bwd07vmTNRS1Ntd2sKvYXx/2GGaEVmGGjKukDmuSfD0="; + }; + + extension = pkgs.stdenv.mkDerivation { + inherit pname version; + + src = import ./nix/build.nix { inherit pkgs cargo-pgrx postgresql; }; + + buildPhase = '' + install --directory $out/usr/share/postgresql/16/extension + cp -r $src/nix/store/wc1a06ip2fajrjkfbw7cvxzw1c949a6g-postgresql-16.4/share/postgresql/extension/* $out/usr/share/postgresql/16/extension + install --directory $out/usr/lib/postgresql/16/lib + cp -r $src/nix/store/wc1a06ip2fajrjkfbw7cvxzw1c949a6g-postgresql-16.4/lib/* $out/usr/lib/postgresql/16/lib + ''; + }; + in + rec { + image = pkgs.dockerTools.buildLayeredImage { + name = pname; + fromImage = postgres; + + contents = [ extension ]; + config = { + Env = [ "POSTGRES_HOST_AUTH_METHOD=trust" ]; + + Expose = 5432; + Cmd = [ "postgres" ]; + Entrypoint = [ "docker-entrypoint.sh" ]; + }; + }; + + deploy = pkgs.writeShellScriptBin "deploy" '' + ${pkgs.skopeo}/bin/skopeo --insecure-policy copy docker-archive:${image} docker://docker.io/frectonz/${pname}:pg16-${version} --dest-creds="frectonz:$ACCESS_TOKEN" + ${pkgs.skopeo}/bin/skopeo --insecure-policy copy docker://docker.io/frectonz/${pname}:pg16-${version} docker://docker.io/frectonz/${pname}:latest --dest-creds="frectonz:$ACCESS_TOKEN" + ''; + } + ); + formatter = forAllSystems (pkgs: pkgs.nixfmt-rfc-style); }; } diff --git a/nix/build.nix b/nix/build.nix new file mode 100644 index 0000000..4b40858 --- /dev/null +++ b/nix/build.nix @@ -0,0 +1,89 @@ +{ + pkgs, + cargo-pgrx, + postgresql, +}: + +let + postgresMajor = pkgs.lib.versions.major postgresql.version; + + preBuildAndTest = '' + export PGRX_HOME=$(mktemp -d) + mkdir -p $PGRX_HOME/${postgresMajor} + + cp -r -L ${postgresql}/. $PGRX_HOME/${postgresMajor}/ + chmod -R ugo+w $PGRX_HOME/${postgresMajor} + cp -r -L ${postgresql.lib}/lib/. $PGRX_HOME/${postgresMajor}/lib/ + + ${cargo-pgrx}/bin/cargo-pgrx pgrx init \ + --pg${postgresMajor} $PGRX_HOME/${postgresMajor}/bin/pg_config + ''; + + filterCargoSources = + orig_path: type: + let + path = (toString orig_path); + base = baseNameOf path; + parentDir = baseNameOf (dirOf path); + + matchesSuffix = pkgs.lib.any (suffix: pkgs.lib.hasSuffix suffix base) [ + ".rs" + ".toml" + ".control" + ]; + + # Cargo.toml already captured above + isCargoFile = base == "Cargo.lock"; + + # .cargo/config.toml already captured above + isCargoConfig = parentDir == ".cargo" && base == "config"; + in + (type == "directory") || matchesSuffix || isCargoFile || isCargoConfig; +in +pkgs.rustPlatform.buildRustPackage { + pname = "pglite-fusion"; + version = "0.0.0"; + + src = pkgs.lib.cleanSourceWith { + src = pkgs.lib.cleanSource ../.; + filter = filterCargoSources; + }; + cargoLock.lockFile = ../Cargo.lock; + + doCheck = false; + buildNoDefaultFeatures = true; + buildFeatures = [ "pg${postgresMajor}" ]; + + preBuild = preBuildAndTest; + preCheck = preBuildAndTest; + postPatch = "patchShebangs ."; + + postBuild = '' + if [ -f "pglite_fusion.control" ]; then + export NIX_PGLIBDIR=${postgresql.out}/share/postgresql/extension/ + ${cargo-pgrx}/bin/cargo-pgrx pgrx package --pg-config ${postgresql}/bin/pg_config --out-dir the-thing + export NIX_PGLIBDIR=$PGRX_HOME/${postgresMajor}/lib + fi + ''; + + preFixup = '' + if [ -f "pglite_fusion.control" ]; then + ${cargo-pgrx}/bin/cargo-pgrx pgrx stop all + rm -rfv $out/target* + fi + ''; + + installPhase = '' + cp -rp the-thing $out + ''; + + nativeBuildInputs = [ + postgresql + pkgs.rustfmt + postgresql.lib + pkgs.pkg-config + pkgs.rustPlatform.bindgenHook + ]; + + PGRX_PG_SYS_SKIP_BINDING_REWRITE = "1"; +}