pkgs/glitch-soc: upgrade + new attempt at packaging
Stolen from https://git.catgirl.cloud/999eagle/dotfiles-nix
parent
2dc96f189f
commit
049b69e0b4
|
@ -217,7 +217,6 @@ in {
|
||||||
scrcpy
|
scrcpy
|
||||||
krita
|
krita
|
||||||
vlc
|
vlc
|
||||||
# mastodon-update-script
|
|
||||||
libreoffice-qt
|
libreoffice-qt
|
||||||
tokodon
|
tokodon
|
||||||
|
|
||||||
|
@ -267,7 +266,6 @@ in {
|
||||||
# orca-slicer
|
# orca-slicer
|
||||||
# super-slicer-beta
|
# super-slicer-beta
|
||||||
|
|
||||||
mastodon-update-script
|
|
||||||
deploy-rs
|
deploy-rs
|
||||||
go
|
go
|
||||||
pry
|
pry
|
||||||
|
|
|
@ -53,6 +53,8 @@
|
||||||
mode = "440";
|
mode = "440";
|
||||||
};
|
};
|
||||||
age.secrets.keycloak.file = ../../secrets/mail/keycloak.age;
|
age.secrets.keycloak.file = ../../secrets/mail/keycloak.age;
|
||||||
|
age.secrets.mastodonActiveRecordSecrets.file =
|
||||||
|
../../secrets/mastodon-activerecord.age;
|
||||||
|
|
||||||
age.secrets.notbotEnvironment.file = ../../secrets/notbotEnvironment.age;
|
age.secrets.notbotEnvironment.file = ../../secrets/notbotEnvironment.age;
|
||||||
|
|
||||||
|
@ -301,7 +303,8 @@
|
||||||
ALLOWED_PRIVATE_ADDRESSES = "127.1.33.7";
|
ALLOWED_PRIVATE_ADDRESSES = "127.1.33.7";
|
||||||
GITHUB_REPOSITORY = "arachnist/mastodon/tree/meow";
|
GITHUB_REPOSITORY = "arachnist/mastodon/tree/meow";
|
||||||
};
|
};
|
||||||
package = pkgs.glitchSoc;
|
extraEnvFiles = [ config.age.secrets.mastodonActiveRecordSecrets.path ];
|
||||||
|
package = pkgs.glitch-soc;
|
||||||
};
|
};
|
||||||
|
|
||||||
services.vaultwarden = {
|
services.vaultwarden = {
|
||||||
|
|
|
@ -1,8 +1,23 @@
|
||||||
self: super: {
|
self: super:
|
||||||
|
let inherit (self) lib;
|
||||||
|
in {
|
||||||
cass = super.callPackage ../pkgs/cass.nix { };
|
cass = super.callPackage ../pkgs/cass.nix { };
|
||||||
notbot = super.callPackage ../pkgs/notbot.nix { };
|
notbot = super.callPackage ../pkgs/notbot.nix { };
|
||||||
glitchSoc = self.callPackage ../pkgs/glitch-soc { };
|
glitch-soc = let
|
||||||
mastodon-update-script = self.callPackage ../pkgs/mastodonUpdate.nix { };
|
emoji-reactions = import ../pkgs/glitch-soc/emoji.nix {
|
||||||
|
inherit (super) fetchpatch fetchurl;
|
||||||
|
};
|
||||||
|
file-post-patch = lib.concatMapStringsSep "\n" (f: ''
|
||||||
|
mkdir -p "$(dirname "${f.name}")"
|
||||||
|
cp -f "${f.src}" "${f.name}"
|
||||||
|
'') emoji-reactions.files;
|
||||||
|
tl-replacer = super.callPackage ../pkgs/glitch-soc/tl-replacer { };
|
||||||
|
in self.callPackage ../pkgs/glitch-soc {
|
||||||
|
srcPostPatch = ''${file-post-patch}
|
||||||
|
${tl-replacer}/tl-replacer ${tl-replacer}/tl-replacer.yaml
|
||||||
|
'';
|
||||||
|
inherit (emoji-reactions) patches;
|
||||||
|
};
|
||||||
|
|
||||||
python3 = super.python3.override {
|
python3 = super.python3.override {
|
||||||
packageOverrides = self: super: {
|
packageOverrides = self: super: {
|
||||||
|
|
|
@ -1,161 +1,26 @@
|
||||||
{ lib, stdenv, nodejs-slim, bundlerEnv, nixosTests, yarn, callPackage, ruby
|
{ callPackage, patches ? [ ], srcPostPatch ? "", mastodon, }:
|
||||||
, writeShellScript, fetchYarnDeps, prefetch-yarn-deps, brotli, fixup-yarn-lock
|
let
|
||||||
|
src = callPackage ./source.nix {
|
||||||
# Allow building a fork or custom version of Mastodon:
|
inherit patches;
|
||||||
, pname ? "mastodon", version ? srcOverride.version, patches ? [ ]
|
postPatch = srcPostPatch;
|
||||||
# src is a package
|
|
||||||
, srcOverride ? callPackage ./source.nix { inherit patches; }
|
|
||||||
, gemset ? ./. + "/gemset.nix", yarnHash ? srcOverride.yarnHash }:
|
|
||||||
|
|
||||||
stdenv.mkDerivation rec {
|
|
||||||
inherit pname version;
|
|
||||||
|
|
||||||
src = srcOverride;
|
|
||||||
|
|
||||||
mastodonGems = bundlerEnv {
|
|
||||||
name = "${pname}-gems-${version}";
|
|
||||||
inherit version gemset ruby;
|
|
||||||
gemdir = src;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
mastodonModules = stdenv.mkDerivation {
|
# the upstream nix package doesn't support yarn berry yet so here we fucking go
|
||||||
pname = "${pname}-modules";
|
# see https://github.com/NixOS/nixpkgs/issues/254369 and https://github.com/NixOS/nixpkgs/issues/277697
|
||||||
inherit src version;
|
yarn-deps = callPackage ./yarn.nix {
|
||||||
|
inherit src;
|
||||||
yarnOfflineCache = fetchYarnDeps {
|
hash = src.yarnHash;
|
||||||
yarnLock = "${src}/yarn.lock";
|
|
||||||
hash = yarnHash;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
nativeBuildInputs = [
|
# this is mastodon built from the glitch source
|
||||||
prefetch-yarn-deps
|
# modules are unpatched though
|
||||||
nodejs-slim
|
glitch-1 = mastodon.override {
|
||||||
yarn
|
pname = "glitch";
|
||||||
fixup-yarn-lock
|
srcOverride = src;
|
||||||
mastodonGems
|
gemset = ./. + "/gemset.nix";
|
||||||
mastodonGems.wrappedRuby
|
|
||||||
brotli
|
|
||||||
];
|
|
||||||
|
|
||||||
RAILS_ENV = "production";
|
|
||||||
NODE_ENV = "production";
|
|
||||||
|
|
||||||
buildPhase = ''
|
|
||||||
runHook preBuild
|
|
||||||
|
|
||||||
export HOME=$PWD
|
|
||||||
# This option is needed for openssl-3 compatibility
|
|
||||||
# Otherwise we encounter this upstream issue: https://github.com/mastodon/mastodon/issues/17924
|
|
||||||
export NODE_OPTIONS=--openssl-legacy-provider
|
|
||||||
fixup-yarn-lock ~/yarn.lock
|
|
||||||
yarn config --offline set yarn-offline-mirror $yarnOfflineCache
|
|
||||||
yarn install --offline --frozen-lockfile --ignore-engines --ignore-scripts --no-progress
|
|
||||||
|
|
||||||
patchShebangs ~/bin
|
|
||||||
patchShebangs ~/node_modules
|
|
||||||
|
|
||||||
# skip running yarn install
|
|
||||||
rm -rf ~/bin/yarn
|
|
||||||
|
|
||||||
OTP_SECRET=precompile_placeholder SECRET_KEY_BASE=precompile_placeholder \
|
|
||||||
rails assets:precompile
|
|
||||||
yarn cache clean --offline
|
|
||||||
rm -rf ~/node_modules/.cache
|
|
||||||
|
|
||||||
# Create missing static gzip and brotli files
|
|
||||||
gzip --best --keep ~/public/assets/500.html
|
|
||||||
gzip --best --keep ~/public/packs/report.html
|
|
||||||
find ~/public/assets -maxdepth 1 -type f -name '.*.json' \
|
|
||||||
-exec gzip --best --keep --force {} ';'
|
|
||||||
brotli --best --keep ~/public/packs/report.html
|
|
||||||
find ~/public/assets -type f -regextype posix-extended -iregex '.*\.(css|js|json|html)' \
|
|
||||||
-exec brotli --best --keep {} ';'
|
|
||||||
|
|
||||||
runHook postBuild
|
|
||||||
'';
|
|
||||||
|
|
||||||
installPhase = ''
|
|
||||||
runHook preInstall
|
|
||||||
|
|
||||||
mkdir -p $out/public
|
|
||||||
cp -r node_modules $out/node_modules
|
|
||||||
cp -r public/assets $out/public
|
|
||||||
cp -r public/packs $out/public
|
|
||||||
|
|
||||||
runHook postInstall
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
propagatedBuildInputs = [ mastodonGems.wrappedRuby ];
|
modules = callPackage ./modules.nix { inherit glitch-1 yarn-deps; };
|
||||||
nativeBuildInputs = [ brotli ];
|
|
||||||
buildInputs = [ mastodonGems nodejs-slim ];
|
|
||||||
|
|
||||||
buildPhase = ''
|
glitch-2 = glitch-1.overrideAttrs (old: { mastodonModules = modules; });
|
||||||
runHook preBuild
|
in glitch-2
|
||||||
|
|
||||||
ln -s $mastodonModules/node_modules node_modules
|
|
||||||
ln -s $mastodonModules/public/assets public/assets
|
|
||||||
ln -s $mastodonModules/public/packs public/packs
|
|
||||||
|
|
||||||
patchShebangs bin/
|
|
||||||
for b in $(ls $mastodonGems/bin/)
|
|
||||||
do
|
|
||||||
if [ ! -f bin/$b ]; then
|
|
||||||
ln -s $mastodonGems/bin/$b bin/$b
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Remove execute permissions
|
|
||||||
chmod 0444 public/emoji/*.svg
|
|
||||||
|
|
||||||
# Create missing static gzip and brotli files
|
|
||||||
find public -maxdepth 1 -type f -regextype posix-extended -iregex '.*\.(css|js|svg|txt|xml)' \
|
|
||||||
-exec gzip --best --keep --force {} ';' \
|
|
||||||
-exec brotli --best --keep {} ';'
|
|
||||||
find public/emoji -type f -name '.*.svg' \
|
|
||||||
-exec gzip --best --keep --force {} ';' \
|
|
||||||
-exec brotli --best --keep {} ';'
|
|
||||||
ln -s assets/500.html.gz public/500.html.gz
|
|
||||||
ln -s assets/500.html.br public/500.html.br
|
|
||||||
ln -s packs/sw.js.gz public/sw.js.gz
|
|
||||||
ln -s packs/sw.js.br public/sw.js.br
|
|
||||||
ln -s packs/sw.js.map.gz public/sw.js.map.gz
|
|
||||||
ln -s packs/sw.js.map.br public/sw.js.map.br
|
|
||||||
|
|
||||||
rm -rf log
|
|
||||||
ln -s /var/log/mastodon log
|
|
||||||
ln -s /tmp tmp
|
|
||||||
|
|
||||||
runHook postBuild
|
|
||||||
'';
|
|
||||||
|
|
||||||
installPhase = let
|
|
||||||
run-streaming = writeShellScript "run-streaming.sh" ''
|
|
||||||
# NixOS helper script to consistently use the same NodeJS version the package was built with.
|
|
||||||
${nodejs-slim}/bin/node ./streaming
|
|
||||||
'';
|
|
||||||
in ''
|
|
||||||
runHook preInstall
|
|
||||||
|
|
||||||
mkdir -p $out
|
|
||||||
cp -r * $out/
|
|
||||||
ln -s ${run-streaming} $out/run-streaming.sh
|
|
||||||
|
|
||||||
runHook postInstall
|
|
||||||
'';
|
|
||||||
|
|
||||||
passthru = {
|
|
||||||
tests.mastodon = nixosTests.mastodon;
|
|
||||||
# run with: nix-shell ./maintainers/scripts/update.nix --argstr package mastodon
|
|
||||||
updateScript = ./update.sh;
|
|
||||||
};
|
|
||||||
|
|
||||||
meta = with lib; {
|
|
||||||
description =
|
|
||||||
"Self-hosted, globally interconnected microblogging software based on ActivityPub";
|
|
||||||
homepage = "https://joinmastodon.org";
|
|
||||||
license = licenses.agpl3Plus;
|
|
||||||
platforms = [ "x86_64-linux" "i686-linux" "aarch64-linux" ];
|
|
||||||
maintainers = with maintainers; [ happy-river erictapen izorkin ghuntley ];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
# autogenerated file
|
||||||
|
{fetchpatch, fetchurl}: {
|
||||||
|
patches = [
|
||||||
|
(fetchpatch {
|
||||||
|
url = "https://github.com/glitch-soc/mastodon/pull/2462/commits/227a8d71b3b1f475c29f864e3572ee37ed24b139.patch";
|
||||||
|
hash = "sha256-0uCMtrOyLjXw9OxFLFjP5geQa2XJaNUPAwfaiFbomdM=";
|
||||||
|
})
|
||||||
|
(fetchpatch {
|
||||||
|
url = "https://github.com/glitch-soc/mastodon/pull/2462/commits/14c0e46ef42f853dc26e385723bd30a26d3c6aca.patch";
|
||||||
|
hash = "sha256-mPTn1tSFX16H3qw6tTMoY8ZEpSFw0WwMoAlwdMdN5o8=";
|
||||||
|
})
|
||||||
|
(fetchpatch {
|
||||||
|
url = "https://github.com/glitch-soc/mastodon/pull/2462/commits/28ecb2a4bebc080fba4aebfd611f502220fd2bd1.patch";
|
||||||
|
hash = "sha256-W54/zXblx89YfWqkkeHYpYArDPzI63S+XgPw5kbtVIQ=";
|
||||||
|
})
|
||||||
|
(fetchpatch {
|
||||||
|
url = "https://github.com/glitch-soc/mastodon/pull/2462/commits/938175d5e856e54f4469f746a019955ecd16a47b.patch";
|
||||||
|
hash = "sha256-ShXE7LykbImUByMjpKpMrB+mvjV9Y+txwNWBQwlHYX0=";
|
||||||
|
})
|
||||||
|
(fetchpatch {
|
||||||
|
url = "https://github.com/glitch-soc/mastodon/pull/2462/commits/22fc82dfeedda84b251b136a2175e5e3e9ab0e44.patch";
|
||||||
|
hash = "sha256-oZx8NOdXqEOZImaTmubFQGXPlJQkgquLofOpKaEo7Gg=";
|
||||||
|
})
|
||||||
|
(fetchpatch {
|
||||||
|
url = "https://github.com/glitch-soc/mastodon/pull/2462/commits/03ea7618ad2f885a027c4c9a73eaf71510ebc622.patch";
|
||||||
|
hash = "sha256-d9G3JijFI5gKBDfHX5RE766+v3e0GUBT6blmRxtAB/s=";
|
||||||
|
})
|
||||||
|
(fetchpatch {
|
||||||
|
url = "https://github.com/glitch-soc/mastodon/pull/2462/commits/4d832522b9e566a6e59778490ec50bc3ea2d2fd2.patch";
|
||||||
|
hash = "sha256-XaV5ibRFQgReLKlTGLzA1hN8Z4EBEQhF/2GtWSFAuu0=";
|
||||||
|
})
|
||||||
|
(fetchpatch {
|
||||||
|
url = "https://github.com/glitch-soc/mastodon/pull/2462/commits/a27b8387419b8229451b048a646f2799305b76a6.patch";
|
||||||
|
hash = "sha256-//d36ZolRH5Z9/2tBGWAUjlbIbaXb2MQGrDUVrlPHGI=";
|
||||||
|
})
|
||||||
|
(fetchpatch {
|
||||||
|
url = "https://github.com/glitch-soc/mastodon/pull/2462/commits/0838432237260d207adf57ec3f76ea8745ae7dc9.patch";
|
||||||
|
hash = "sha256-F73oi+m6905u9N/iE+0kG8a/raSPW7znDeoNSjzrWJc=";
|
||||||
|
})
|
||||||
|
(fetchpatch {
|
||||||
|
url = "https://github.com/glitch-soc/mastodon/pull/2462/commits/09b64d761a6f2559eb6ed34a5e5c628894b87189.patch";
|
||||||
|
hash = "sha256-WgWtfn2UJXUz1elSPlM6PfIOG9xRgP0KVOtJ/35tY44=";
|
||||||
|
})
|
||||||
|
(fetchpatch {
|
||||||
|
url = "https://github.com/glitch-soc/mastodon/pull/2462/commits/11bebd28a2f7942b1c18b40122f1fc93813daaa0.patch";
|
||||||
|
hash = "sha256-Vj2vaxJf6Fyuew4yTZ8T8rH7sVmey3zkmlYX++L4DzQ=";
|
||||||
|
})
|
||||||
|
(fetchpatch {
|
||||||
|
url = "https://github.com/glitch-soc/mastodon/pull/2462/commits/a2ab3f541cbc2ab73fd32da1864fc889e0e0513e.patch";
|
||||||
|
hash = "sha256-BZPpWyRRSkVPVygyNYrdX115Bj6usVR4gIzsbG0zgRs=";
|
||||||
|
})
|
||||||
|
(fetchpatch {
|
||||||
|
url = "https://github.com/glitch-soc/mastodon/pull/2462/commits/4311fff076c79335fd2a76b4abfe4f43e03a84ab.patch";
|
||||||
|
hash = "sha256-zWDnO/KLpl0aBaxS2DTt0W7WCeR29gU4N//5gZvJcwg=";
|
||||||
|
})
|
||||||
|
(fetchpatch {
|
||||||
|
url = "https://github.com/glitch-soc/mastodon/pull/2462/commits/0d68ecf75dec23d23f1ad063d3200f9b2f6158c3.patch";
|
||||||
|
hash = "sha256-ygSdBo/9UKp9LAHNvpjvqcRF5uFpRWaqOH86gLnxYwU=";
|
||||||
|
})
|
||||||
|
(fetchpatch {
|
||||||
|
url = "https://github.com/glitch-soc/mastodon/pull/2462/commits/d54affc10782bec9965ad4d913f66bc0aab91ac5.patch";
|
||||||
|
hash = "sha256-haFsOBTGWWbhEvbWWVf9Sawdw/CCUa3ZVRCz3AHNlF4=";
|
||||||
|
})
|
||||||
|
(fetchpatch {
|
||||||
|
url = "https://github.com/glitch-soc/mastodon/pull/2462/commits/a12b2ad57af11c8be5eb1a2fbd776d5da209bbfa.patch";
|
||||||
|
hash = "sha256-+oUPXiHicgK1/r1lovl4IH6jZ7rDUWwBuVCDywzCPCk=";
|
||||||
|
})
|
||||||
|
(fetchpatch {
|
||||||
|
url = "https://github.com/glitch-soc/mastodon/pull/2462/commits/aae6e1b1fd5073ffdb6e6cdcbdbe9bae01808f84.patch";
|
||||||
|
hash = "sha256-4IdH4YHyBfzbb+sdtn/EB9l+7zOl9QDzh/qdA15wFoQ=";
|
||||||
|
})
|
||||||
|
(fetchpatch {
|
||||||
|
url = "https://github.com/glitch-soc/mastodon/pull/2462/commits/b07f5f89d4411e71e0a616ccffebb2140452e728.patch";
|
||||||
|
hash = "sha256-SUOgcCBXlfsyMHKYvkkvgiOkW1uzLruI+jy5uf9f5kA=";
|
||||||
|
})
|
||||||
|
(fetchpatch {
|
||||||
|
url = "https://github.com/glitch-soc/mastodon/pull/2462/commits/ba37843ec23cca1e537d462374f479371c4115fb.patch";
|
||||||
|
hash = "sha256-mweLZ82np2r/kbbDJscwOomHgruULHxxlu9zhR51PNQ=";
|
||||||
|
})
|
||||||
|
(fetchpatch {
|
||||||
|
url = "https://github.com/glitch-soc/mastodon/pull/2462/commits/13c9fa62fa1d07a89c34a96352e9e05f464e2e81.patch";
|
||||||
|
hash = "sha256-TrDCWaBVAwPi5umG0FcQVdONTl2LtJ1oWi/rwgz3Y3U=";
|
||||||
|
})
|
||||||
|
(fetchpatch {
|
||||||
|
url = "https://github.com/glitch-soc/mastodon/pull/2462/commits/40ae5aed66ac0dd2dfc70c5111d439db6b8e988e.patch";
|
||||||
|
hash = "sha256-33l5CWQ5TSzXtBMJs68nmyya0l96WTCW/ZxRwCkbswM=";
|
||||||
|
})
|
||||||
|
(fetchpatch {
|
||||||
|
url = "https://github.com/glitch-soc/mastodon/pull/2462/commits/9b54b27bf76b155e9866a0deb52d26df35a1e101.patch";
|
||||||
|
hash = "sha256-HIU/DuRJPRi+nQL3hWSHN6PQAoXDL0CPV91IoArhpOE=";
|
||||||
|
})
|
||||||
|
(fetchpatch {
|
||||||
|
url = "https://github.com/glitch-soc/mastodon/pull/2462/commits/11900689bf510f19fd21376367da4d0b6371bf2a.patch";
|
||||||
|
hash = "sha256-/Krv3fWX7IYotZJ2I/uKLqIOOB3F/OSkcWdYaUbZEI0=";
|
||||||
|
})
|
||||||
|
];
|
||||||
|
files = [
|
||||||
|
{
|
||||||
|
src = fetchurl {
|
||||||
|
url = "https://github.com/glitch-soc/mastodon/raw/11900689bf510f19fd21376367da4d0b6371bf2a/app%2Fjavascript%2Fimages%2Fmailer-new%2Fheading%2Freaction.png";
|
||||||
|
hash = "sha256-6QLPNTSigxXryjO0IbvZFOQjWrnwrQHr5Mb0ZJllMLk=";
|
||||||
|
};
|
||||||
|
name = "app/javascript/images/mailer-new/heading/reaction.png";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
src = fetchurl {
|
||||||
|
url = "https://github.com/glitch-soc/mastodon/raw/11900689bf510f19fd21376367da4d0b6371bf2a/app%2Fjavascript%2Fimages%2Fmailer%2Ficon_add.png";
|
||||||
|
hash = "sha256-UYDdj5GKsg1cfVTx04hwsEURk6iKZfQCMAA2UFT0SJA=";
|
||||||
|
};
|
||||||
|
name = "app/javascript/images/mailer/icon_add.png";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,13 +0,0 @@
|
||||||
diff --git a/lib/mastodon/version.rb b/lib/mastodon/version.rb
|
|
||||||
index efc643fb4..5d7f3d4d0 100644
|
|
||||||
--- a/lib/mastodon/version.rb
|
|
||||||
+++ b/lib/mastodon/version.rb
|
|
||||||
@@ -17,7 +17,7 @@ module Mastodon
|
|
||||||
end
|
|
||||||
|
|
||||||
def default_prerelease
|
|
||||||
- 'alpha.2'
|
|
||||||
+ 'alpha.3'
|
|
||||||
end
|
|
||||||
|
|
||||||
def prerelease
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
# this is mostly copied from upstream mastodon packaging, but modified for yarn-berry deps
|
||||||
|
{ stdenv, nodejs-slim, yarn-berry, brotli,
|
||||||
|
# previous inputs
|
||||||
|
glitch-1, yarn-deps, }:
|
||||||
|
stdenv.mkDerivation {
|
||||||
|
pname = "glitch-modules";
|
||||||
|
inherit (glitch-1) src version;
|
||||||
|
|
||||||
|
yarnOfflineCache = yarn-deps;
|
||||||
|
|
||||||
|
nativeBuildInputs =
|
||||||
|
[ glitch-1.mastodonGems glitch-1.mastodonGems.wrappedRuby ]
|
||||||
|
++ [ nodejs-slim yarn-berry brotli ];
|
||||||
|
|
||||||
|
RAILS_ENV = "production";
|
||||||
|
NODE_ENV = "production";
|
||||||
|
|
||||||
|
buildPhase = ''
|
||||||
|
runHook preBuild
|
||||||
|
|
||||||
|
export HOME=$PWD
|
||||||
|
# This option is needed for openssl-3 compatibility
|
||||||
|
# Otherwise we encounter this upstream issue: https://github.com/mastodon/mastodon/issues/17924
|
||||||
|
export NODE_OPTIONS=--openssl-legacy-provider
|
||||||
|
|
||||||
|
export YARN_ENABLE_TELEMETRY=0
|
||||||
|
mkdir -p ~/.yarn/berry
|
||||||
|
ln -sf $yarnOfflineCache ~/.yarn/berry/cache
|
||||||
|
|
||||||
|
yarn install --immutable --immutable-cache
|
||||||
|
|
||||||
|
patchShebangs ~/bin
|
||||||
|
patchShebangs ~/node_modules
|
||||||
|
|
||||||
|
# skip running yarn install
|
||||||
|
rm -rf ~/bin/yarn
|
||||||
|
|
||||||
|
OTP_SECRET=precompile_placeholder \
|
||||||
|
SECRET_KEY_BASE=precompile_placeholder \
|
||||||
|
ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY=precompile_placeholder \
|
||||||
|
ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT=precompile_placeholder \
|
||||||
|
ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY=precompile_placeholder \
|
||||||
|
rails assets:precompile
|
||||||
|
yarn cache clean
|
||||||
|
rm -rf ~/node_modules/.cache
|
||||||
|
|
||||||
|
# Create missing static gzip and brotli files
|
||||||
|
gzip --best --keep ~/public/assets/500.html
|
||||||
|
gzip --best --keep ~/public/packs/report.html
|
||||||
|
find ~/public/assets -maxdepth 1 -type f -name '.*.json' \
|
||||||
|
-exec gzip --best --keep --force {} ';'
|
||||||
|
brotli --best --keep ~/public/packs/report.html
|
||||||
|
find ~/public/assets -type f -regextype posix-extended -iregex '.*\.(css|js|json|html)' \
|
||||||
|
-exec brotli --best --keep {} ';'
|
||||||
|
|
||||||
|
runHook postBuild
|
||||||
|
'';
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
runHook preInstall
|
||||||
|
|
||||||
|
mkdir -p $out/public
|
||||||
|
cp -r node_modules $out/node_modules
|
||||||
|
cp -r public/assets $out/public
|
||||||
|
cp -r public/packs $out/public
|
||||||
|
|
||||||
|
runHook postInstall
|
||||||
|
'';
|
||||||
|
}
|
|
@ -1,15 +1,23 @@
|
||||||
# This file was generated by pkgs.mastodon.updateScript.
|
{ lib, applyPatches, fetchFromGitHub, patches ? [ ], postPatch ? "", yarn-berry
|
||||||
{ fetchFromGitHub, applyPatches, patches ? [ ] }:
|
, gawk, gnused, }:
|
||||||
let version = "be934df67eea4d7a5b7b6e657f1f2e8ceec5bb63";
|
(applyPatches {
|
||||||
in (applyPatches {
|
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "arachnist";
|
owner = "glitch-soc";
|
||||||
repo = "mastodon";
|
repo = "mastodon";
|
||||||
rev = "${version}";
|
rev = "7c81666f7f8d7c0321d12899680f6e0b5bf3757a";
|
||||||
hash = "sha256-zXBxKC3jf4TaoOlDBgE9FdH9BJ9dwRgvKWLkooq3hPs=";
|
hash = "sha256-myxCbzi6mDwSzlRULW2695ggPUGOEAn6K2PWQ/tuov4=";
|
||||||
};
|
};
|
||||||
patches = patches ++ [ ./local-new-fixes.patch ];
|
inherit patches;
|
||||||
|
nativeBuildInputs = [ gawk gnused ];
|
||||||
|
postPatch = postPatch
|
||||||
|
+ lib.optionalString (lib.versionAtLeast yarn-berry.version "4.1.0") ''
|
||||||
|
# this is for yarn starting with 4.1.0 because fuck everything amirite
|
||||||
|
# see also https://github.com/yarnpkg/berry/pull/6083
|
||||||
|
echo "patching cachekey in yarn.lock"
|
||||||
|
cacheKey="$(awk -e '/cacheKey:/ {print $2}' yarn.lock)"
|
||||||
|
sed -i -Ee 's|^ checksum: ([^/]*)$| checksum: '$cacheKey'/\1|g;' yarn.lock
|
||||||
|
'';
|
||||||
}) // {
|
}) // {
|
||||||
inherit version;
|
version = "unstable-2024-05-14";
|
||||||
yarnHash = "sha256-P7KswzsCusyiS4MxUFnC1HYMTQ6fLpIwd97AglCukIk=";
|
yarnHash = "sha256-tw5EiPWNpzGjjLkTx++W82bA5ZZiJCzU1BELgXU+d1M=";
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
{ stdenv, ruby }:
|
||||||
|
|
||||||
|
stdenv.mkDerivation {
|
||||||
|
pname = "tl-replacer";
|
||||||
|
version = "0.1";
|
||||||
|
src = ./.;
|
||||||
|
|
||||||
|
buildInputs = [ ruby ];
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out
|
||||||
|
cp -r $src/tl-replacer* $out
|
||||||
|
'';
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
#!/usr/bin/ruby
|
||||||
|
require 'json'
|
||||||
|
require 'yaml'
|
||||||
|
require 'pp'
|
||||||
|
|
||||||
|
config = YAML.load_file(ARGV[0])
|
||||||
|
def update_translations(hash, replacements)
|
||||||
|
hash.reduce({}) do |acc, (key,value)|
|
||||||
|
if value.is_a?(Hash)
|
||||||
|
acc[key] = update_translations(value, replacements)
|
||||||
|
elsif value.is_a?(String)
|
||||||
|
replacements.to_a.sort_by do |x| 0-x[0].length end.each do |from, to|
|
||||||
|
if value.match?(from) then
|
||||||
|
puts "updating #{key} from #{value} with #{to}"
|
||||||
|
value.gsub!(from, to)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
acc[key] = value
|
||||||
|
end
|
||||||
|
acc
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
config["paths"].each do |dir|
|
||||||
|
yaml = []
|
||||||
|
Dir.entries(dir).each do |fname|
|
||||||
|
config["types"]["yaml"].each do |type_ext|
|
||||||
|
yaml += [File.join(dir, fname)] if File.extname(fname) == type_ext
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
json = []
|
||||||
|
Dir.entries(dir).each do |fname|
|
||||||
|
config["types"]["json"].each do |type_ext|
|
||||||
|
json += [File.join(dir, fname)] if File.extname(fname) == type_ext
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
config["replacements"].each do |lang, conf|
|
||||||
|
yaml_files = []
|
||||||
|
json_files = []
|
||||||
|
|
||||||
|
yaml.each do |fname|
|
||||||
|
conf["filename-patterns"].each do |pattern|
|
||||||
|
yaml_files += [fname] if File.fnmatch?(pattern, fname)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
yaml_files.each do |fname|
|
||||||
|
puts "modifying #{fname}"
|
||||||
|
tl = YAML.load_file(fname)
|
||||||
|
tl = update_translations(tl, conf["strings"])
|
||||||
|
|
||||||
|
File.open(fname, 'w') do |file|
|
||||||
|
file.write(tl.to_yaml(options = {:line_width => -1}))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
json.each do |fname|
|
||||||
|
conf["filename-patterns"].each do |pattern|
|
||||||
|
json_files += [fname] if File.fnmatch?(pattern, fname)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
json_files.each do |fname|
|
||||||
|
puts "modifying #{fname}"
|
||||||
|
tl = JSON.load_file(fname)
|
||||||
|
tl = update_translations(tl, conf["strings"])
|
||||||
|
|
||||||
|
File.open(fname, 'w') do |file|
|
||||||
|
file.write(JSON.pretty_generate(tl))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,50 @@
|
||||||
|
paths:
|
||||||
|
- "app/javascript/flavours/glitch/locales"
|
||||||
|
- "app/javascript/mastodon/locales"
|
||||||
|
- "config/locales-glitch"
|
||||||
|
- "config/locales"
|
||||||
|
types:
|
||||||
|
"yaml":
|
||||||
|
- ".yml"
|
||||||
|
- ".yaml"
|
||||||
|
"json":
|
||||||
|
- ".json"
|
||||||
|
replacements:
|
||||||
|
en:
|
||||||
|
filename-patterns:
|
||||||
|
- "*/en*.*"
|
||||||
|
- "*/*.en*.*"
|
||||||
|
strings:
|
||||||
|
"posts": "meows"
|
||||||
|
"post": "meow"
|
||||||
|
"Posts": "Meows"
|
||||||
|
"Post": "Meow"
|
||||||
|
pl:
|
||||||
|
filename-patterns:
|
||||||
|
- "*/pl.*"
|
||||||
|
- "*/*.pl.*"
|
||||||
|
strings:
|
||||||
|
"Ostatni post": "Ostatnie miauknięcie"
|
||||||
|
"Ten wpis nie będzie widoczny pod podanymi hasztagami, ponieważ jest oznaczony jako niepubliczny.": "To miauknięcie nie będzie widoczne pod podanymi hasztagami, ponieważ jest oznaczone jako niepubliczne."
|
||||||
|
"ten wpis": "to miauknięcie"
|
||||||
|
"Ten wpis": "To miauknięcie"
|
||||||
|
"Twój wpis": "Twoje miauknięcie"
|
||||||
|
"Twój post został podbity": "Twoje miauknięcie zostało podbite"
|
||||||
|
"nowy wpis": "nowe miauknięcie"
|
||||||
|
"swój pierwszy post": "swoje pierwsze miauknięcie"
|
||||||
|
"Ten wpis nie może zostać podbity": "To miauknięcie nie może zostać podbite"
|
||||||
|
"Post": "Miauknięcie"
|
||||||
|
"post": "miauknięcie"
|
||||||
|
"Posty": "Miauknięcia"
|
||||||
|
"posty": "miauknięcia"
|
||||||
|
"postów": "miauknięć"
|
||||||
|
"Wpis": "Miauknięcie"
|
||||||
|
"Wpisy": "Miauknięcia"
|
||||||
|
"wpis": "miauknięcie"
|
||||||
|
"wpisy": "miauknięcia"
|
||||||
|
"wpisach": "miauknięciach"
|
||||||
|
"wpisów": "miauknięć"
|
||||||
|
"wpisu": "miauknięcia"
|
||||||
|
"wpisie": "miauknięciu"
|
||||||
|
"Opublikuj": "Miauknij"
|
||||||
|
"wzmianki": "miauknięcia"
|
|
@ -0,0 +1,20 @@
|
||||||
|
#!/usr/bin/env nix-shell
|
||||||
|
#!nix-shell -i bash -p curl jq nix-prefetch
|
||||||
|
|
||||||
|
cd "$(dirname "${BASH_SOURCE[0]}")"
|
||||||
|
|
||||||
|
# kinda hacky? seems to work fine though :3
|
||||||
|
echo -e "# autogenerated file\n{fetchpatch, fetchurl}: {\n patches = [" > emoji.nix
|
||||||
|
curl 'https://api.github.com/repos/glitch-soc/mastodon/pulls/2462/commits' | jq -r 'map(.sha) | .[]' | while read sha; do
|
||||||
|
url="https://github.com/glitch-soc/mastodon/pull/2462/commits/$sha.patch"
|
||||||
|
hash="$(nix-prefetch fetchpatch --url "$url")"
|
||||||
|
echo -e ' (fetchpatch {\n url = "'$url'";\n hash = "'$hash'";\n })' >> emoji.nix
|
||||||
|
done
|
||||||
|
echo -e ' ];\n files = [' >> emoji.nix
|
||||||
|
curl 'https://api.github.com/repos/glitch-soc/mastodon/pulls/2462/files?per_page=100' | jq -c 'map(select(has("patch")|not) | {name:.filename,url:.raw_url}) | .[]' | while read json; do
|
||||||
|
name="$(jq -r '.name' <<<"$json")"
|
||||||
|
url="$(jq -r '.url' <<<"$json")"
|
||||||
|
hash="$(nix-prefetch fetchurl --url "$url")"
|
||||||
|
echo -e ' {\n src = fetchurl {\n url = "'$url'";\n hash = "'$hash'";\n };\n name = "'$name'";\n }' >> emoji.nix
|
||||||
|
done
|
||||||
|
echo -e ' ];\n}' >> emoji.nix
|
|
@ -1,112 +1,35 @@
|
||||||
#!/usr/bin/env nix-shell
|
#!/usr/bin/env nix-shell
|
||||||
#! nix-shell -i bash -p bundix coreutils diffutils nix-prefetch-github gnused jq prefetch-yarn-deps
|
#! nix-shell -i bash -p curl jq coreutils nix-prefetch-github gnused bundix prefetch-yarn-deps
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
OWNER=mastodon
|
cd "$(dirname "$0")"
|
||||||
REPO=mastodon
|
|
||||||
|
|
||||||
POSITIONAL=()
|
commit="$(curl -SsL "$1")"
|
||||||
while [[ $# -gt 0 ]]; do
|
rev="$(jq -r '.commit.sha' <<<"$commit")"
|
||||||
key="$1"
|
date="$(jq -r '.commit.commit.committer.date' <<<"$commit")"
|
||||||
|
date="$(date --date="$date" --iso-8601=date)"
|
||||||
|
echo "current commit is $rev, prefetching..."
|
||||||
|
|
||||||
case $key in
|
hash="$(nix-prefetch-github glitch-soc mastodon --rev "$rev" | jq -r '.hash')"
|
||||||
--owner)
|
|
||||||
OWNER="$2"
|
|
||||||
shift # past argument
|
|
||||||
shift # past value
|
|
||||||
;;
|
|
||||||
--repo)
|
|
||||||
REPO="$2"
|
|
||||||
shift # past argument
|
|
||||||
shift # past value
|
|
||||||
;;
|
|
||||||
--ver)
|
|
||||||
VERSION="$2"
|
|
||||||
shift # past argument
|
|
||||||
shift # past value
|
|
||||||
;;
|
|
||||||
--rev)
|
|
||||||
REVISION="$2"
|
|
||||||
shift # past argument
|
|
||||||
shift # past value
|
|
||||||
;;
|
|
||||||
--patches)
|
|
||||||
PATCHES="$2"
|
|
||||||
shift # past argument
|
|
||||||
shift # past value
|
|
||||||
;;
|
|
||||||
*) # unknown option
|
|
||||||
POSITIONAL+=("$1")
|
|
||||||
shift # past argument
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
if [[ -n "$POSITIONAL" ]]; then
|
sed -i -Ee "s|^( *rev = )\".*\";|\\1\"$rev\";|g;" ./source.nix
|
||||||
echo "Usage: update.sh [--owner OWNER] [--repo REPO] [--ver VERSION] [--rev REVISION] [--patches PATCHES]"
|
sed -i -Ee "s|^( *hash = )\".*\";|\\1\"$hash\";|g;" ./source.nix
|
||||||
echo "OWNER and REPO must be paths on github."
|
sed -i -Ee "s|^( *version = )\".*\";|\\1\"unstable-$date\";|g;" ./source.nix
|
||||||
echo "If REVISION is not provided, the latest tag from github.com/mastodon/mastodon is fetched and VERSION is calculated from it."
|
|
||||||
echo "If OWNER and REPO are not provided, it defaults they default to mastodon and mastodon."
|
|
||||||
echo "PATCHES, if provided, should be one or more Nix expressions separated by spaces."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -z "$REVISION" ]]; then
|
echo "building source"
|
||||||
REVISION="$(curl ${GITHUB_TOKEN:+" -u \":$GITHUB_TOKEN\""} -s "https://api.github.com/repos/$OWNER/$REPO/releases" | jq -r 'map(select(.prerelease == false)) | .[0].tag_name')"
|
srcdir="$(nix-build --no-out-link -E '(import <nixpkgs> {}).callPackage ./source.nix {}')"
|
||||||
fi
|
|
||||||
|
|
||||||
VERSION="$(echo "$REVISION" | cut -c2-)"
|
echo "creating gemset"
|
||||||
|
rm -f gemset.nix
|
||||||
|
bundix --lockfile $srcdir/Gemfile.lock --gemfile $srcdir/Gemfile
|
||||||
|
echo "" >> gemset.nix
|
||||||
|
|
||||||
rm -f gemset.nix source.nix
|
# TODO: find a way to automate this
|
||||||
cd "$(dirname "${BASH_SOURCE[0]}")" || exit 1
|
sed -i -Ee "s|^( *yarnHash = )\".*\";|\\1\"\";|g;" ./source.nix
|
||||||
|
# echo "creating yarn hash"
|
||||||
|
# hash="$(prefetch-yarn-deps $srcdir/yarn.lock)"
|
||||||
|
# hash="$(nix hash --to-sri --type sha256 "$hash")"
|
||||||
|
# sed -i -Ee "s|^( *yarnHash = )\".*\";|\\1\"$hash\";|g;' ./source.nix
|
||||||
|
|
||||||
WORK_DIR=$(mktemp -d)
|
./update-emoji-patch.sh
|
||||||
|
|
||||||
# Check that working directory was created.
|
|
||||||
if [[ -z "$WORK_DIR" || ! -d "$WORK_DIR" ]]; then
|
|
||||||
echo "Could not create temporary directory"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Delete the working directory on exit.
|
|
||||||
function cleanup {
|
|
||||||
# Report errors, if any, from nix-prefetch-git
|
|
||||||
grep "fatal" $WORK_DIR/nix-prefetch-git.out >/dev/stderr || true
|
|
||||||
rm -rf "$WORK_DIR"
|
|
||||||
}
|
|
||||||
trap cleanup EXIT
|
|
||||||
|
|
||||||
echo "Fetching source code $REVISION"
|
|
||||||
JSON=$(nix-prefetch-github "$OWNER" "$REPO" --rev "$REVISION" 2> $WORK_DIR/nix-prefetch-git.out)
|
|
||||||
HASH=$(echo "$JSON" | jq -r .hash)
|
|
||||||
|
|
||||||
cat > source.nix << EOF
|
|
||||||
# This file was generated by pkgs.mastodon.updateScript.
|
|
||||||
{ fetchFromGitHub, applyPatches, patches ? [] }:
|
|
||||||
let
|
|
||||||
version = "$VERSION";
|
|
||||||
in
|
|
||||||
(
|
|
||||||
applyPatches {
|
|
||||||
src = fetchFromGitHub {
|
|
||||||
owner = "$OWNER";
|
|
||||||
repo = "$REPO";
|
|
||||||
rev = "v\${version}";
|
|
||||||
hash = "$HASH";
|
|
||||||
};
|
|
||||||
patches = patches ++ [$PATCHES];
|
|
||||||
}) // {
|
|
||||||
inherit version;
|
|
||||||
yarnHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
SOURCE_DIR="$(nix-build --no-out-link -E '(import <nixpkgs> {}).callPackage ./source.nix {}')"
|
|
||||||
|
|
||||||
echo "Creating gemset.nix"
|
|
||||||
bundix --lockfile="$SOURCE_DIR/Gemfile.lock" --gemfile="$SOURCE_DIR/Gemfile"
|
|
||||||
echo "" >> gemset.nix # Create trailing newline to please EditorConfig checks
|
|
||||||
|
|
||||||
echo "Creating yarn-hash.nix"
|
|
||||||
YARN_HASH="$(prefetch-yarn-deps "$SOURCE_DIR/yarn.lock")"
|
|
||||||
YARN_HASH="$(nix hash to-sri --type sha256 "$YARN_HASH")"
|
|
||||||
sed -i "s/sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=/$YARN_HASH/g" source.nix
|
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
"4+glitch+meow"
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
{ stdenvNoCC, yarn-berry, cacert, src, hash, }:
|
||||||
|
stdenvNoCC.mkDerivation {
|
||||||
|
name = "yarn-deps";
|
||||||
|
nativeBuildInputs = [ yarn-berry cacert ];
|
||||||
|
inherit src;
|
||||||
|
|
||||||
|
dontInstall = true;
|
||||||
|
|
||||||
|
NODE_EXTRA_CA_CERTS = "${cacert}/etc/ssl/certs/ca-bundle.crt";
|
||||||
|
|
||||||
|
buildPhase = ''
|
||||||
|
mkdir -p $out
|
||||||
|
|
||||||
|
export HOME=$(mktemp -d)
|
||||||
|
echo $HOME
|
||||||
|
|
||||||
|
export YARN_ENABLE_TELEMETRY=0
|
||||||
|
export YARN_COMPRESSION_LEVEL=0
|
||||||
|
|
||||||
|
cache="$(yarn config get cacheFolder)"
|
||||||
|
if ! yarn install --immutable --mode skip-build; then
|
||||||
|
cp yarn.lock yarn.lock.bak
|
||||||
|
yarn install --mode skip-build
|
||||||
|
diff -u yarn.lock.bak yarn.lock > yarn.lock.diff
|
||||||
|
echo "yarn build failed! diff generated as yarn.lock.diff"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cp -r $cache/* $out/
|
||||||
|
'';
|
||||||
|
|
||||||
|
outputHashAlgo = "sha256";
|
||||||
|
outputHash = hash;
|
||||||
|
outputHashMode = "recursive";
|
||||||
|
}
|
|
@ -80,6 +80,8 @@ in {
|
||||||
++ [ meta.hosts.zorigami.publicKey ];
|
++ [ meta.hosts.zorigami.publicKey ];
|
||||||
"secrets/synapseExtraConfig.age".publicKeys = meta.users.ar
|
"secrets/synapseExtraConfig.age".publicKeys = meta.users.ar
|
||||||
++ [ meta.hosts.zorigami.publicKey ];
|
++ [ meta.hosts.zorigami.publicKey ];
|
||||||
|
"secrets/mastodon-activerecord.age".publicKeys = meta.users.ar
|
||||||
|
++ [ meta.hosts.zorigami.publicKey ];
|
||||||
"secrets/gitea-runner-token-zorigami.age".publicKeys = meta.users.ar
|
"secrets/gitea-runner-token-zorigami.age".publicKeys = meta.users.ar
|
||||||
++ [ meta.hosts.zorigami.publicKey ];
|
++ [ meta.hosts.zorigami.publicKey ];
|
||||||
"secrets/gitea-runner-token-scylla.age".publicKeys = meta.users.ar
|
"secrets/gitea-runner-token-scylla.age".publicKeys = meta.users.ar
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue