update lemmy to 0.18.2
authorself <self@awful.systems>
Mon, 17 Jul 2023 21:08:50 +0000 (14:08 -0700)
committerself <self@awful.systems>
Mon, 17 Jul 2023 21:08:50 +0000 (14:08 -0700)
lemmy/package.json
lemmy/pin.json
lemmy/server.nix
lemmy/ui.nix
lemmy/update.py [new file with mode: 0644]

index 40d2eb26d6221c00a688c11610fcc90832335dc8..9ec97ece37f03231f382ed46f639c05119629eae 100644 (file)
@@ -1,6 +1,6 @@
 {
   "name": "lemmy-ui",
-  "version": "0.18.1",
+  "version": "0.18.2",
   "description": "An isomorphic UI for lemmy",
   "repository": "https://github.com/LemmyNet/lemmy-ui",
   "license": "AGPL-3.0",
@@ -8,7 +8,7 @@
   "scripts": {
     "analyze": "webpack --mode=none",
     "prebuild:dev": "yarn clean && node generate_translations.js",
-    "build:dev": "webpack --env COMMIT_HASH=$(git rev-parse --short HEAD) --mode=development",
+    "build:dev": "webpack --env LEMMY_UI_DISABLE_CSP=true --env COMMIT_HASH=$(git rev-parse --short HEAD) --mode=development",
     "prebuild:prod": "yarn clean && node generate_translations.js",
     "build:prod": "webpack --env COMMIT_HASH=$(git rev-parse --short HEAD) --mode=production",
     "clean": "yarn run rimraf dist",
@@ -50,7 +50,7 @@
     "clean-webpack-plugin": "^4.0.0",
     "cookie": "^0.5.0",
     "copy-webpack-plugin": "^11.0.0",
-    "cross-fetch": "^3.1.5",
+    "cross-fetch": "^4.0.0",
     "css-loader": "^6.7.3",
     "date-fns": "^2.30.0",
     "emoji-mart": "^5.4.0",
     "express": "~4.18.2",
     "history": "^5.3.0",
     "html-to-text": "^9.0.5",
-    "i18next": "^22.4.15",
-    "inferno": "^8.1.1",
-    "inferno-create-element": "^8.1.1",
+    "i18next": "^23.2.8",
+    "inferno": "^8.2.2",
+    "inferno-create-element": "^8.2.2",
     "inferno-helmet": "^5.2.1",
-    "inferno-hydrate": "^8.1.1",
+    "inferno-hydrate": "^8.2.2",
     "inferno-i18next-dess": "0.0.2",
-    "inferno-router": "^8.1.1",
-    "inferno-server": "^8.1.1",
+    "inferno-router": "^8.2.2",
+    "inferno-server": "^8.2.2",
     "jwt-decode": "^3.1.2",
-    "lemmy-js-client": "0.18.0-rc.2",
+    "lemmy-js-client": "0.18.1",
     "lodash.isequal": "^4.5.0",
     "lodash.merge": "^4.6.2",
     "markdown-it": "^13.0.1",
     "mini-css-extract-plugin": "^2.7.5",
     "register-service-worker": "^1.7.2",
     "run-node-webpack-plugin": "^1.3.0",
-    "sanitize-html": "^2.10.0",
-    "sass": "^1.62.1",
-    "sass-loader": "^13.2.2",
+    "sanitize-html": "^2.11.0",
+    "sass": "^1.63.6",
+    "sass-loader": "^13.3.2",
     "serialize-javascript": "^6.0.1",
     "service-worker-webpack": "^1.0.0",
     "sharp": "^0.32.1",
     "tippy.js": "^6.3.7",
     "toastify-js": "^1.12.0",
     "tributejs": "^5.1.3",
-    "webpack": "5.82.1",
-    "webpack-cli": "^5.1.1",
+    "webpack": "5.88.1",
+    "webpack-cli": "^5.1.4",
     "webpack-node-externals": "^3.0.0"
   },
   "devDependencies": {
     "@types/lodash.isequal": "^4.5.6",
     "@types/markdown-it": "^12.2.3",
     "@types/markdown-it-container": "^2.0.5",
-    "@types/node": "^20.1.2",
+    "@types/node": "^20.4.0",
     "@types/path-browserify": "^1.0.0",
     "@types/sanitize-html": "^2.9.0",
     "@types/serialize-javascript": "^5.0.1",
     "@types/toastify-js": "^1.11.1",
-    "@typescript-eslint/eslint-plugin": "^5.59.5",
-    "@typescript-eslint/parser": "^5.59.5",
-    "eslint": "^8.40.0",
+    "@typescript-eslint/eslint-plugin": "^5.61.0",
+    "@typescript-eslint/parser": "^5.61.0",
+    "eslint": "^8.44.0",
     "eslint-plugin-inferno": "^7.32.2",
     "eslint-plugin-jsx-a11y": "^6.7.1",
     "eslint-plugin-prettier": "^4.2.1",
     "husky": "^8.0.3",
     "import-sort-style-module": "^6.0.0",
-    "lint-staged": "^13.2.2",
+    "lint-staged": "^13.2.3",
     "prettier": "^2.8.8",
     "prettier-plugin-import-sort": "^0.0.7",
     "prettier-plugin-organize-imports": "^3.2.2",
-    "prettier-plugin-packagejson": "^2.4.3",
+    "prettier-plugin-packagejson": "^2.4.4",
     "rimraf": "^5.0.0",
     "sortpack": "^2.3.4",
     "style-loader": "^3.3.2",
-    "terser": "^5.17.3",
-    "typescript": "^5.0.4",
+    "terser": "^5.18.2",
+    "typescript": "^5.1.6",
     "typescript-language-server": "^3.3.2",
     "webpack-bundle-analyzer": "^4.9.0",
-    "webpack-dev-server": "4.15.0"
+    "webpack-dev-server": "4.15.1"
   },
   "packageManager": "yarn@1.22.19",
   "engines": {
index 85fef5a4f9fee6d2d1fc9face03333a4233dc0ed..489b5ecff47725e587d1a53d7c51beb1ad5b5cb8 100644 (file)
@@ -1,7 +1,8 @@
 {
-  "version": "0.18.1",
-  "serverSha256": "sha256-jYbrbIRyXo2G113ReG32oZ56ed2FEB/ZBcqYAxoxzGQ=",
-  "serverCargoSha256": "sha256-7DNMNPSjzYY45DlR6Eo2q6QdwrMrRb51cFOnXfOuub0=",
-  "uiSha256": "sha256-tc7fGA4okIv+3kq5t6I+EN+owdekCgAdk0EtkDgodIU=",
-  "uiYarnDepsSha256": "sha256-/T1PQ0XsGY82/RlLq94hJgv8Yx1bIf2gcklhgtPu1RM="
+  "serverVersion": "0.18.2",
+  "uiVersion": "0.18.2",
+  "serverSha256": "sha256-T08CjsRREgGJb1vXJrYihYaCin8NNHtsG+2PUHoI4Ho=",
+  "serverCargoSha256": "sha256-nTZcLOpsbdeGzpz3PzgXZEGZHMbvSDA5rB2A3S9tMF8=",
+  "uiSha256": "sha256-qFFnmdCONjfPyfp8v0VonPQP8G5b2DVpxEUAQT731Z0=",
+  "uiYarnDepsSha256": "sha256-fRJpA9WstNNNOePoqotJKYmlikkcjc34iM0WO8+a/3Q="
 }
index 890cc59df5dc5ba97c10edfacfb9d9e0597c28aa..fa016593bb08605b618662a67dff7d7b024aa916 100644 (file)
@@ -2,7 +2,7 @@
 , Security, protobuf, rustfmt, nixosTests }:
 let
   pinData = lib.importJSON ./pin.json;
-  version = pinData.version;
+  version = pinData.serverVersion;
 in rustPlatform.buildRustPackage rec {
   inherit version;
   pname = "lemmy-server";
@@ -16,7 +16,7 @@ in rustPlatform.buildRustPackage rec {
   };
 
   preConfigure = ''
-    echo "pub const VERSION: &str = \"${version}\";" > "crates/utils/src/version.rs"
+    echo 'pub const VERSION: &str = "${version}";' > crates/utils/src/version.rs
   '';
 
   cargoSha256 = pinData.serverCargoSha256;
@@ -35,7 +35,7 @@ in rustPlatform.buildRustPackage rec {
   PROTOC_INCLUDE = "${protobuf}/include";
   nativeBuildInputs = [ protobuf rustfmt ];
 
-  passthru.updateScript = ./update.sh;
+  passthru.updateScript = ./update.py;
   passthru.tests.lemmy-server = nixosTests.lemmy;
 
   doCheck = false;
index 63551c3f22e9099eb54a52d3a09a03f462555bf3..d1d4ce6f679f099cd9d4b51b40e8f0256961774b 100644 (file)
@@ -23,7 +23,7 @@ let
   };
 
   name = "lemmy-ui";
-  version = pinData.version;
+  version = pinData.uiVersion;
 
   src = fetchFromGitHub {
     owner = "LemmyNet";
@@ -45,10 +45,6 @@ in mkYarnPackage {
     sha256 = pinData.uiYarnDepsSha256;
   };
 
-  postPatch = ''
-    echo "export const VERSION = '${version}';" > "src/shared/version.ts"
-  '';
-
   yarnPreBuild = ''
     export npm_config_nodedir=${nodejs}
   '';
@@ -58,6 +54,7 @@ in mkYarnPackage {
     export HOME=$PWD/yarn_home
 
     ln -sf $PWD/node_modules $PWD/deps/lemmy-ui/
+    echo 'export const VERSION = "${version}";' > $PWD/deps/lemmy-ui/src/shared/version.ts
 
     yarn --offline build:prod
   '';
diff --git a/lemmy/update.py b/lemmy/update.py
new file mode 100644 (file)
index 0000000..95bd59d
--- /dev/null
@@ -0,0 +1,177 @@
+#! /usr/bin/env nix-shell
+#! nix-shell -i python3 -p python3 python3.pkgs.semver nix-prefetch-github
+from urllib.request import Request, urlopen
+import dataclasses
+import subprocess
+import hashlib
+import os.path
+import semver
+import base64
+from typing import (
+    Optional,
+    Dict,
+    List,
+)
+import json
+import os
+
+
+SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
+NIXPKGS = os.path.abspath(os.path.join(SCRIPT_DIR, "../../../../"))
+
+
+OWNER = "LemmyNet"
+UI_REPO = "lemmy-ui"
+SERVER_REPO = "lemmy"
+
+
+@dataclasses.dataclass
+class Pin:
+    serverVersion: str
+    uiVersion: str
+    serverSha256: str = ""
+    serverCargoSha256: str = ""
+    uiSha256: str = ""
+    uiYarnDepsSha256: str = ""
+
+    filename: Optional[str] = None
+
+    def write(self) -> None:
+        if not self.filename:
+            raise ValueError("No filename set")
+
+        with open(self.filename, "w") as fd:
+            pin = dataclasses.asdict(self)
+            del pin["filename"]
+            json.dump(pin, fd, indent=2)
+            fd.write("\n")
+
+
+def github_get(path: str) -> Dict:
+    """Send a GET request to Gituhb, optionally adding GITHUB_TOKEN auth header"""
+    url = f"https://api.github.com/{path.lstrip('/')}"
+    print(f"Retreiving {url}")
+
+    req = Request(url)
+
+    if "GITHUB_TOKEN" in os.environ:
+        req.add_header("authorization", f"Bearer {os.environ['GITHUB_TOKEN']}")
+
+    with urlopen(req) as resp:
+        return json.loads(resp.read())
+
+
+def get_latest_release(owner: str, repo: str) -> str:
+    return github_get(f"/repos/{owner}/{repo}/releases/latest")["tag_name"]
+
+
+def sha256_url(url: str) -> str:
+    sha256 = hashlib.sha256()
+    with urlopen(url) as resp:
+        while data := resp.read(1024):
+            sha256.update(data)
+    return "sha256-" + base64.urlsafe_b64encode(sha256.digest()).decode()
+
+
+def prefetch_github(owner: str, repo: str, rev: str) -> str:
+    """Prefetch github rev and return sha256 hash"""
+    print(f"Prefetching {owner}/{repo}({rev})")
+
+    proc = subprocess.run(
+        ["nix-prefetch-github", owner, repo, "--rev", rev, "--fetch-submodules"],
+        check=True,
+        stdout=subprocess.PIPE,
+    )
+
+    sha256 = json.loads(proc.stdout)["sha256"]
+    if not sha256.startswith("sha256-"):  # Work around bug in nix-prefetch-github
+        return "sha256-" + sha256
+
+    return sha256
+
+
+def get_latest_tag(owner: str, repo: str, prerelease: bool = False) -> str:
+    """Get the latest tag from a Github Repo"""
+    tags: List[str] = []
+
+    # As the Github API doesn't have any notion of "latest" for tags we need to
+    # collect all of them and sort so we can figure out the latest one.
+    i = 0
+    while i <= 100:  # Prevent infinite looping
+        i += 1
+        resp = github_get(f"/repos/{owner}/{repo}/tags?page={i}")
+        if not resp:
+            break
+
+        # Filter out unparseable tags
+        for tag in resp:
+            try:
+                parsed = semver.Version.parse(tag["name"])
+                if (
+                    semver.Version.parse(tag["name"])
+                    and not prerelease
+                    and parsed.prerelease
+                ):  # Filter out release candidates
+                    continue
+            except ValueError:
+                continue
+            else:
+                tags.append(tag["name"])
+
+    # Sort and return latest
+    return sorted(tags, key=lambda name: semver.Version.parse(name))[-1]
+
+
+def get_fod_hash(attr: str) -> str:
+    """
+    Get fixed output hash for attribute.
+    This depends on a fixed output derivation with an empty hash.
+    """
+
+    print(f"Getting fixed output hash for {attr}")
+
+    proc = subprocess.run(["nix-build", NIXPKGS, "-A", attr], stderr=subprocess.PIPE)
+    if proc.returncode != 1:
+        raise ValueError("Expected nix-build to fail")
+
+    # Iterate list in reverse order so we get the "got:" line early
+    for line in proc.stderr.decode().split("\n")[::-1]:
+        cols = line.split()
+        if cols and cols[0] == "got:":
+            return cols[1]
+
+    raise ValueError("No fixed output hash found")
+
+
+def make_server_pin(pin: Pin, attr: str) -> None:
+    pin.serverSha256 = prefetch_github(OWNER, SERVER_REPO, pin.serverVersion)
+    pin.write()
+    pin.serverCargoSha256 = get_fod_hash(attr)
+    pin.write()
+
+
+def make_ui_pin(pin: Pin, package_json: str, attr: str) -> None:
+    # Save a copy of package.json
+    print("Getting package.json")
+    with urlopen(
+        f"https://raw.githubusercontent.com/{OWNER}/{UI_REPO}/{pin.uiVersion}/package.json"
+    ) as resp:
+        with open(os.path.join(SCRIPT_DIR, package_json), "wb") as fd:
+            fd.write(resp.read())
+
+    pin.uiSha256 = prefetch_github(OWNER, UI_REPO, pin.uiVersion)
+    pin.write()
+    pin.uiYarnDepsSha256 = get_fod_hash(attr)
+    pin.write()
+
+
+if __name__ == "__main__":
+    # Get server version
+    server_version = get_latest_tag(OWNER, SERVER_REPO)
+
+    # Get UI version (not always the same as lemmy-server)
+    ui_version = get_latest_tag(OWNER, UI_REPO)
+
+    pin = Pin(server_version, ui_version, filename=os.path.join(SCRIPT_DIR, "pin.json"))
+    make_server_pin(pin, "lemmy-server")
+    make_ui_pin(pin, "package.json", "lemmy-ui")