diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 04d95e7..339a0eb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,4 +48,4 @@ jobs: with: nix_path: nixpkgs=channel:nixos-unstable - - run: nix flake show + - run: nix build diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 877f558..0eb6ebf 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -159,34 +159,35 @@ jobs: working-directory: artifacts run: cosign sign-blob --yes checksums.txt --bundle checksums.txt.bundle - - name: Update flake.nix + - uses: cachix/install-nix-action@526118121621777ccd86f79b04685a9319637641 # v31 + with: + nix_path: nixpkgs=channel:nixos-unstable + + - name: Regenerate scala.lock.json run: | VERSION="${{ inputs.version }}" + # Maven Central propagation can take a few minutes after publish. + for i in $(seq 1 10); do + nix run github:scala-nix/scala-cli-nix -- lock-coords \ + --dep "org.virtuslab::cellar-cli:${VERSION}" \ + --main-class cellar.cli.CellarApp && break + echo "Attempt $i failed, retrying in 30s..." + sleep 30 + done - # Convert hex sha256 to Nix SRI format (sha256-) - sri_hash() { - echo -n "$1" | xxd -r -p | base64 | tr -d '\n' | sed 's/^/sha256-/' - } - - LINUX_X86=$(sri_hash "$(grep "linux-x86_64.tar.gz" artifacts/checksums.txt | awk '{print $1}')") - LINUX_ARM=$(sri_hash "$(grep "linux-aarch64.tar.gz" artifacts/checksums.txt | awk '{print $1}')") - MACOS_ARM=$(sri_hash "$(grep "macos-arm64.tar.gz" artifacts/checksums.txt | awk '{print $1}')") - MACOS_X86=$(sri_hash "$(grep "macos-x86_64.tar.gz" artifacts/checksums.txt | awk '{print $1}')") - - sed -i "0,/version = \".*\";/s|version = \".*\";|version = \"${VERSION}\";|" flake.nix - sed -i "/linux-x86_64/{n;s|hash = \".*\";|hash = \"${LINUX_X86}\";|}" flake.nix - sed -i "/linux-aarch64/{n;s|hash = \".*\";|hash = \"${LINUX_ARM}\";|}" flake.nix - sed -i "/macos-x86_64/{n;s|hash = \".*\";|hash = \"${MACOS_X86}\";|}" flake.nix - sed -i "/macos-arm64/{n;s|hash = \".*\";|hash = \"${MACOS_ARM}\";|}" flake.nix + - name: Update flake.nix + run: | + VERSION="${{ inputs.version }}" + sed -i "s/version = \".*\";/version = \"${VERSION}\";/" flake.nix - name: Commit, tag, and push run: | VERSION="${{ inputs.version }}" git config user.name "github-actions[bot]" git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git add flake.nix - git diff --cached --quiet && echo "No flake changes" && exit 0 - git commit -m "Update flake.nix to ${VERSION}" + git add flake.nix scala.lock.json + git diff --cached --quiet && echo "No changes to commit" && exit 0 + git commit -m "Release ${VERSION}" git push origin main git tag "v${VERSION}" git push origin "v${VERSION}" diff --git a/RELEASING.md b/RELEASING.md index 18e01ae..b56dc79 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -19,12 +19,15 @@ This document describes how to cut a release, what artifacts are produced, and h - Publishes the `lib` and `cli` modules to Maven Central as `org.virtuslab:cellar-lib_3:` and `org.virtuslab:cellar-cli_3:`. - Generates a SHA256 checksum file. - Signs the checksum file using cosign keyless (OIDC). - - Updates `flake.nix` with the new version and SRI hashes, commits to `main`. + - Regenerates `scala.lock.json` from the freshly published Maven coordinates using `scn lock-coords` ([scala-cli-nix](https://github.com/scala-nix/scala-cli-nix)). + - Updates `version` in `flake.nix`, commits `flake.nix` and `scala.lock.json` to `main`. - Creates and pushes a `v` git tag. - Publishes a GitHub Release with all artifacts attached. The Maven publish waits for the native-binary and JAR builds to succeed before uploading — a Sonatype release is immutable, so we must not publish a version whose corresponding GitHub Release assets (referenced by the coursier app descriptor) failed to build. If Sonatype then rejects the upload (e.g. duplicate version, namespace mismatch, signature failure), no GitHub Release is created and no tag is pushed. +The `scala.lock.json` regeneration step retries up to 10 times with 30-second intervals to account for Maven Central propagation delay after publish. + No container images are built or published by this release flow. ## Supported platforms diff --git a/derivation.nix b/derivation.nix new file mode 100644 index 0000000..068ed00 --- /dev/null +++ b/derivation.nix @@ -0,0 +1,8 @@ +{ scala-cli-nix, version }: + +scala-cli-nix.buildCoursierApp { + pname = "cellar"; + inherit version; + lockFile = ./scala.lock.json; + mainClass = "cellar.cli.CellarApp"; +} diff --git a/flake.lock b/flake.lock index efc4226..10cb02a 100644 --- a/flake.lock +++ b/flake.lock @@ -18,7 +18,28 @@ }, "root": { "inputs": { - "nixpkgs": "nixpkgs" + "nixpkgs": "nixpkgs", + "scala-cli-nix": "scala-cli-nix" + } + }, + "scala-cli-nix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1782242239, + "narHash": "sha256-kqPVxdAUFFFDktEcCjd+9mK1cphEKMr6PER4Z6hHVJ4=", + "owner": "scala-nix", + "repo": "scala-cli-nix", + "rev": "ee6c4edc6f1bb418df5eeafe87786410a6a400a9", + "type": "github" + }, + "original": { + "owner": "scala-nix", + "repo": "scala-cli-nix", + "type": "github" } } }, diff --git a/flake.nix b/flake.nix index da04085..9b3741d 100644 --- a/flake.nix +++ b/flake.nix @@ -1,102 +1,30 @@ { description = "Look up the public API of any JVM dependency from the terminal"; - inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + scala-cli-nix = { + url = "github:scala-nix/scala-cli-nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; - outputs = { self, nixpkgs }: + outputs = { self, nixpkgs, scala-cli-nix }: let version = "0.1.0-M9"; - - # Per-platform release artifact metadata - platforms = { - x86_64-linux = { - archive = "cellar-${version}-linux-x86_64.tar.gz"; - hash = "sha256-40JX4uEavG0VO2yMaeJFLm8rt8EQYLhs3F9dygglvxY="; - }; - aarch64-linux = { - archive = "cellar-${version}-linux-aarch64.tar.gz"; - hash = "sha256-2XxcxjpnnOsPkg9lcMBZMc/PCbovujseL9NTIkScXiY="; - }; - x86_64-darwin = { - archive = "cellar-${version}-macos-x86_64.tar.gz"; - hash = "sha256-aGv5hOQOhRycrfjp7zAO3lgveS6T0AqaKDxi74pkmE0="; - }; - aarch64-darwin = { - archive = "cellar-${version}-macos-arm64.tar.gz"; - hash = "sha256-Q23mpapwujuBtfyk/d8oFjmw8796BZP/zxg85tgpXvw="; - }; - }; - - eachSystem = nixpkgs.lib.genAttrs (builtins.attrNames platforms); + systems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ]; + eachSystem = nixpkgs.lib.genAttrs systems; in { packages = eachSystem (system: let - pkgs = nixpkgs.legacyPackages.${system}; - meta = platforms.${system}; - src = pkgs.fetchurl { - url = "https://github.com/VirtusLab/cellar/releases/download/v${version}/${meta.archive}"; - hash = meta.hash; + pkgs = import nixpkgs { + inherit system; + overlays = [ scala-cli-nix.overlays.default ]; }; in { - default = pkgs.stdenv.mkDerivation { - pname = "cellar"; - inherit version src; - - sourceRoot = "."; - - nativeBuildInputs = pkgs.lib.optionals pkgs.stdenv.hostPlatform.isLinux [ - pkgs.autoPatchelfHook - pkgs.glibc - pkgs.zlib - ]; - - unpackPhase = '' - tar xzf $src - ''; - - installPhase = '' - mkdir -p $out/bin - cp cellar $out/bin/cellar - chmod +x $out/bin/cellar - ''; - - meta = with pkgs.lib; { - description = "Look up the public API of any JVM dependency from the terminal"; - homepage = "https://github.com/VirtusLab/cellar"; - license = licenses.mpl20; - platforms = [ system ]; - mainProgram = "cellar"; - }; - }; - - # Install a locally-built binary into the nix profile. - # Usage: ./mill cli.nativeImage && nix profile install --impure .#dev - dev = let - binary = builtins.path { - path = builtins.toPath "${builtins.getEnv "PWD"}/out/cli/nativeImage.dest/native-executable"; - name = "cellar-native-executable"; - }; - in pkgs.stdenv.mkDerivation { - pname = "cellar"; - version = "dev"; - dontUnpack = true; - - installPhase = '' - mkdir -p $out/bin - cp ${binary} $out/bin/cellar - chmod +x $out/bin/cellar - ''; - - meta = with pkgs.lib; { - description = "Look up the public API of any JVM dependency from the terminal (dev build)"; - homepage = "https://github.com/VirtusLab/cellar"; - license = licenses.mpl20; - platforms = [ system ]; - mainProgram = "cellar"; - }; - }; + default = pkgs.callPackage ./derivation.nix { inherit version; }; } ); diff --git a/scala.lock.json b/scala.lock.json new file mode 100644 index 0000000..e14b882 --- /dev/null +++ b/scala.lock.json @@ -0,0 +1,121 @@ +{ + "dependencies": [ + { + "sha256": "OA529lAByYzWLHso5/iZtgkhhRmgKHkqSEviB371KnI=", + "url": "https://repo1.maven.org/maven2/ch/epfl/scala/tasty-query_3/1.7.0/tasty-query_3-1.7.0.jar" + }, + { + "sha256": "K8oTN3Jp8zpXW/adfoSvW5EkMVZgYq2EWbvtye1TnTo=", + "url": "https://repo1.maven.org/maven2/co/fs2/fs2-core_3/3.11.0/fs2-core_3-3.11.0.jar" + }, + { + "sha256": "iI6009BvNxzxSxwddOiA92nzdK4+M4KZV57WLYQIefk=", + "url": "https://repo1.maven.org/maven2/co/fs2/fs2-io_3/3.11.0/fs2-io_3-3.11.0.jar" + }, + { + "sha256": "Cdz2y1DslaqBj+7G7YhRJjHB7cQOjLpA/h924SuXYgw=", + "url": "https://repo1.maven.org/maven2/com/comcast/ip4s-core_3/3.6.0/ip4s-core_3-3.6.0.jar" + }, + { + "sha256": "MujJhkU2nQVICqSFSHwQ0zFH6FeHYKhbUgTbGLo/U10=", + "url": "https://repo1.maven.org/maven2/com/github/pureconfig/pureconfig-core_3/0.17.10/pureconfig-core_3-0.17.10.jar" + }, + { + "sha256": "moeOOawIhNMK/w692tjlk1Tv92AOgz4v5SNzlm9YEmM=", + "url": "https://repo1.maven.org/maven2/com/monovore/decline-effect_3/2.4.1/decline-effect_3-2.4.1.jar" + }, + { + "sha256": "FD3U1rV2G0CVVHHF948zcWS0u21Rlfm1fw4Ruu3TE00=", + "url": "https://repo1.maven.org/maven2/com/monovore/decline_3/2.4.1/decline_3-2.4.1.jar" + }, + { + "sha256": "SksK/7IqlXJAnTpr3pnOPyBFxVHK3Byn/glpCJLFJsM=", + "url": "https://repo1.maven.org/maven2/com/typesafe/config/1.4.5/config-1.4.5.jar" + }, + { + "sha256": "dZL+SceJtVQpSDGFrCKsbaQ2gKOcU7gYxQvKD7fdang=", + "url": "https://repo1.maven.org/maven2/io/get-coursier/interface/1.0.28/interface-1.0.28.jar" + }, + { + "sha256": "daw2bo7LaR4Gp+hQQe7Q9nkZpkblJi+gkBIlaYwQQ3U=", + "url": "https://repo1.maven.org/maven2/org/scala-lang/modules/scala-asm/9.9.0-scala-1/scala-asm-9.9.0-scala-1.jar" + }, + { + "sha256": "p9n/OHsFlubmL+YJVEg+Mcu1h1ih7FcWerwsCYKM2gE=", + "url": "https://repo1.maven.org/maven2/org/scala-lang/scala-library/3.8.1/scala-library-3.8.1.jar" + }, + { + "sha256": "4SeOyxKgqhbnZEBURQJ5wlRux7dr27aIisgumm75rHE=", + "url": "https://repo1.maven.org/maven2/org/scala-lang/scala3-compiler_3/3.8.1/scala3-compiler_3-3.8.1.jar" + }, + { + "sha256": "ixyn2NtnhQqam1uDr6DlLPDQ1BuBGMY3oT0z8RHsga8=", + "url": "https://repo1.maven.org/maven2/org/scala-lang/scala3-interfaces/3.8.1/scala3-interfaces-3.8.1.jar" + }, + { + "sha256": "XpruRQyaFYDYYQl0RI6ewVJZJUt3rkUVBhnB4u2PATc=", + "url": "https://repo1.maven.org/maven2/org/scala-lang/scala3-library_3/3.8.1/scala3-library_3-3.8.1.jar" + }, + { + "sha256": "kHC+2OchuPiAJBNKyuWGs0v98gkq8jk016NZn/CF09U=", + "url": "https://repo1.maven.org/maven2/org/scala-lang/scala3-tasty-inspector_3/3.8.1/scala3-tasty-inspector_3-3.8.1.jar" + }, + { + "sha256": "OpQLU5cbO5CLt/EgL/pAnQ5cZ8++wD8xqlmS3hK0QL0=", + "url": "https://repo1.maven.org/maven2/org/scala-lang/tasty-core_3/3.8.1/tasty-core_3-3.8.1.jar" + }, + { + "sha256": "K6zFdh4DkgoijlydILM9nFHUOq8vUuj4OezmMJZuuIA=", + "url": "https://repo1.maven.org/maven2/org/scala-sbt/compiler-interface/1.10.7/compiler-interface-1.10.7.jar" + }, + { + "sha256": "HWuR76QrcPwGTK7W1iliN04Tsnc3+IWofITGZ7ML5iU=", + "url": "https://repo1.maven.org/maven2/org/scala-sbt/util-interface/1.10.7/util-interface-1.10.7.jar" + }, + { + "sha256": "mR7vOKAZiT7WXXfY2O8WuF/615ntJ9XwzLVHM3/JbG0=", + "url": "https://repo1.maven.org/maven2/org/scodec/scodec-bits_3/1.1.38/scodec-bits_3-1.1.38.jar" + }, + { + "sha256": "0+9XXj5JeWeNwBvx3M5RAhSTtNEft/G+itmCh3wWocA=", + "url": "https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar" + }, + { + "sha256": "yFP3SjGdfbZH3LsfHATEt0yaQRZDoYZGXUa2PbA3M8Y=", + "url": "https://repo1.maven.org/maven2/org/typelevel/cats-core_3/2.11.0/cats-core_3-2.11.0.jar" + }, + { + "sha256": "NapvXrU5w/opPF6A0GUBEtrDWG6pXZJ/JI7bhImLPdI=", + "url": "https://repo1.maven.org/maven2/org/typelevel/cats-effect-kernel_3/3.5.7/cats-effect-kernel_3-3.5.7.jar" + }, + { + "sha256": "xkh/mJURMEmxpuzANedKBbcQ4CWMANFPLZiUq4pdam4=", + "url": "https://repo1.maven.org/maven2/org/typelevel/cats-effect-std_3/3.5.7/cats-effect-std_3-3.5.7.jar" + }, + { + "sha256": "nU7cB0rXaOjImdXVoyJ2Xu0xgOsGy8JKCsjWdD8ZTnA=", + "url": "https://repo1.maven.org/maven2/org/typelevel/cats-effect_3/3.5.7/cats-effect_3-3.5.7.jar" + }, + { + "sha256": "If5JZ1NaJ1jYAIdpxxsdbJtulDb083YxGV200DSoHiA=", + "url": "https://repo1.maven.org/maven2/org/typelevel/cats-kernel_3/2.11.0/cats-kernel_3-2.11.0.jar" + }, + { + "sha256": "LLFM1L2XsfcwPH3Fs7j/b6o/vITOLwkWKI0hm42cFA0=", + "url": "https://repo1.maven.org/maven2/org/typelevel/literally_3/1.1.0/literally_3-1.1.0.jar" + }, + { + "sha256": "uhx6r5q6Mhe5GUKRH/RQ46QVINvfUKttLqxRPH/zOH8=", + "url": "https://repo1.maven.org/maven2/org/virtuslab/cellar-cli_3/0.1.0-M9/cellar-cli_3-0.1.0-M9.jar" + }, + { + "sha256": "+JKcnxZZU7YDKB/TX3nSaisOB/KzhCmst9sXVtIJjU0=", + "url": "https://repo1.maven.org/maven2/org/virtuslab/cellar-lib_3/0.1.0-M9/cellar-lib_3-0.1.0-M9.jar" + } + ], + "javaOptions": [ + ], + "kind": "coursier-app", + "mainClass": "cellar.cli.CellarApp", + "version": 9 +}