This commit is contained in:
Patrick 2024-07-26 21:27:43 +02:00
parent 71547ae3ab
commit 599ce73f9c
Signed by: patrick
GPG key ID: 451F95EFB8BECD0F
11 changed files with 117 additions and 101 deletions

1
.envrc
View file

@ -1,2 +1 @@
watch_file ./devshell.nix
use flake

1
.gitignore vendored
View file

@ -3,3 +3,4 @@
/target
.direnv
.pre-commit-config.yaml

View file

@ -1 +0,0 @@
/nix/store/gw2875m1b8srd62xpzx3zc2avhwa1d8g-pre-commit-config.json

2
Cargo.lock generated
View file

@ -1732,7 +1732,7 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "pr-tracker"
version = "1.2.0"
version = "1.5.0"
dependencies = [
"anyhow",
"askama",

View file

@ -3,8 +3,8 @@
[package]
name = "pr-tracker"
version = "1.2.0"
authors = ["Alyssa Ross <hi@alyssa.is>"]
version = "1.5.0"
authors = ["Patrick <patrick@failmail.dev>"]
edition = "2021"
license = "AGPL-3.0-or-later WITH GPL-3.0-linking-exception"

View file

@ -1,41 +0,0 @@
# SPDX-License-Identifier: CC0-1.0
# SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is>
CARGO = cargo
INSTALL = install
INSTALL_PROGRAM = $(INSTALL)
MKDIR_P = mkdir -p
PROFILE = release
prefix = /usr/local
exec_prefix = $(prefix)
bindir = $(exec_prefix)/bin
all: release
.PHONY: all
cargo-deps: vendor/github_schema.graphql src/merge_commit.graphql
.PHONY: cargo-deps
target/release/pr-tracker: cargo-deps
$(CARGO) build --release
target/debug/pr-tracker: cargo-deps
$(CARGO) build
check: cargo-deps
$(CARGO) test
.PHONY: check
install-dirs:
$(MKDIR_P) $(DESTDIR)$(bindir)
.PHONY: install-dirs
install: install-dirs target/$(PROFILE)/pr-tracker
$(INSTALL_PROGRAM) target/$(PROFILE)/pr-tracker \
$(DESTDIR)$(bindir)/pr-tracker
.PHONY: install
uninstall:
rm -f $(DESTDIR)$(bindir)/pr-tracker
.PHONY: uninstall

View file

@ -1,3 +1,4 @@
SPDX-License-Identifier: CC0-1.0
SPDX-FileCopyrightText: 2024 Patrick <patrick@failmail.dev>
SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is>
SPDX-FileCopyrightText: 2021 Sumner Evans <me@sumnerevans.com>

View file

@ -1,9 +1,6 @@
pr-tracker
==========
Run a web server that displays the path a Nixpkgs pull request will
take through the various release channels. An instance is available
at the time of writing at <https://nixpk.gs/pr-tracker.html>.
at the time of writing at <https://tracker.lel.lol/>.
Installation
@ -21,31 +18,25 @@ Other build dependencies:
Other runtime dependencies:
- Git
In most cases, installation should be as simple as
In most cases, building should be as simple as
make install
cargo run
Usage
-----
The program must be supplied with a local checkout of the monitored
git repository, the remote name in the repository corresponding to
upstream Nixpkgs and a User-Agent string to use when contacting the
GitHub API. Optionally, a "mount" path can be specified, which will be
prefixed to all of the server's routes, so that it can be served at a
non-root HTTP path.
To see usage run:
For example:
```sh
./pr-tracker --help
```
pr-tracker \
--path /var/lib/nixpkgs.git \
--remote nixpkgs \
--user-agent 'pr-tracker (alyssais)' \
--mount pr-tracker
Additionally, a GitHub API token should be supplied on pr-tracker's
standard input.
The following environment variables are expected:
| Name | Usage |
|---|---|
|PR_TRACKER_GITHUB_TOKEN | A github access token to access the github graphql api. |
|PR_TRACKER_MAIL_PASSWD | The password to use for secure email sending. |
pr-tracker expects the socket(s) for it to listen on to be set up for
it by a service supervisor, using the systemd socket activation
@ -57,21 +48,16 @@ outside of a systemd unit, you can use systemd-socket-activate:
Further information on available command line arguments can be
obtained with
pr-tracker --help
Scripts
-----
`scripts/` contains tampermonkey scripts to add buttons directly to github for tracking/subscribing to pull-requests.
Development
-----------
The upstream git repository for pr-tracker is available at
<https://git.qyliss.net/pr-tracker/>.
Bugs and patches can be sent to the author,
Alyssa Ross <hi@alyssa.is>.
For information about how to use git to send a patch email, see
<https://git-send-email.io/>.
<https://github.com/patrickdag/pr-tracker/>.
License
-------

63
scripts/github.user.js Normal file
View file

@ -0,0 +1,63 @@
// ==UserScript==
// @name Nixpkgs subscribe
// @namespace http://tampermonkey.net/
// @version 2024-07-25
// @description try to take over the world!
// @author You
// @match https://github.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=github.com
// @grant GM_getValue
// ==/UserScript==
function addButton() {
const buttonContainerElement = document.querySelector('.gh-header-actions');
const div = document.createElement('div');
div.classList = 'flex-md-order-2 pr_tracker';
const pr= window.location.pathname.split('/')[4];
const btn = document.createElement('button');
btn.classList = 'Button--secondary Button--small Button';
btn.type = 'button';
btn.innerText = `Subscribe`;
btn.addEventListener('click', function() {
window.open('https://tracker.lel.lol/?pr='+pr+'&email=' + GM_getValue("email", "example@example.com"), '_blank').focus();
});
div.appendChild(btn);
buttonContainerElement.firstElementChild.before(div);
const div2 = document.createElement('div');
div2.classList = 'flex-md-order-2';
const btn2 = document.createElement('button');
btn2.classList = 'Button--secondary Button--small Button';
btn2.type = 'button';
btn2.innerText = `Track`;
btn2.addEventListener('click', function() {
window.open('https://tracker.lel.lol/?pr='+pr, '_blank').focus();
});
div2.appendChild(btn2);
buttonContainerElement.firstElementChild.before(div2);
}
function maybeAddButton(){
const loc = window.location.pathname;
if (loc.match("^/NixOS/nixpkgs/pull/[0-9]*") && (document.getElementsByClassName("pr_tracker").length == 0 )){
addButton();
}
setTimeout(maybeAddButton, 250);
}
(function() {
'use strict';
// Your code here...
maybeAddButton();
})();

View file

@ -40,14 +40,14 @@ pub fn send_notification(
encode(recipient)
);
}
let sending_address = env::var("PR_TRACKER_MAIL_ADDRESS").unwrap();
let sending_user = match env::var("PR_TRACKER_MAIL_USER") {
Ok(address) => address,
_ => sending_address.clone(),
let sending_address = &CONFIG.email_address;
let sending_user = match &CONFIG.email_user {
Some(address) => address,
_ => &sending_address,
};
let sending_passwd = env::var("PR_TRACKER_MAIL_PASSWD").unwrap();
let sending_passwd = env::var("PR_TRACKER_MAIL_PASSWD")?;
let sending_server = env::var("PR_TRACKER_MAIL_SERVER").unwrap();
let sending_server = CONFIG.email_server.as_ref();
let email = Message::builder()
.from(format!("PR-Tracker <{}>", sending_address).parse().unwrap())

View file

@ -40,26 +40,49 @@ use tree::Tree;
#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
pub struct Config {
/// The URL under which the site is hosted.
/// Used to generate unsubscribe links and such.
#[arg(long)]
url: String,
/// The path to the local checkout of nixpkgs.
#[arg(long)]
path: PathBuf,
/// The git remote corresponding to upstream nixpkgs
#[arg(long)]
remote: PathBuf,
/// The user agent to use when accessing the github API.
#[arg(long)]
user_agent: OsString,
/// Optional mountpoint if the webserver is not running at the root.
#[arg(long, default_value = "/")]
mount: String,
/// Folder to save the subscription data into.
#[arg(long, default_value = "data")]
data_folder: String,
/// The email sender to use when sending notification.
#[arg(long)]
email_address: String,
/// The user used for authorizing the email sending.
/// Defaults to the sending address.
#[arg(long)]
email_user: Option<String>,
/// The mail server to use for sending.
#[arg(long)]
email_server: String,
/// A whitelist of allowed emails to subscribet.
/// No list or an empty list disables the whitelisting, to blacklist all mails
/// supply a whitelist containing an invalid email.
#[arg(long)]
email_white_list: Option<PathBuf>,
#[arg(long)]
url: String,
}
pub static CONFIG: Lazy<Config> = Lazy::new(Config::parse);
@ -77,23 +100,8 @@ static WHITE_LIST: Lazy<HashSet<String>> = Lazy::new(|| {
static GITHUB_TOKEN: Lazy<OsString> = Lazy::new(|| {
use std::env;
use std::io::{stdin, BufRead, BufReader};
use std::os::unix::prelude::*;
match env::var_os("PR_TRACKER_GITHUB_TOKEN") {
Some(token) => token,
None => {
let mut bytes = Vec::with_capacity(41);
if let Err(e) = BufReader::new(stdin()).read_until(b'\n', &mut bytes) {
eprintln!("pr-tracker: read: {}", e);
exit(74)
}
if bytes.last() == Some(&b'\n') {
bytes.pop();
}
OsString::from_vec(bytes)
}
}
env::var_os("PR_TRACKER_GITHUB_TOKEN").unwrap()
});
#[derive(Debug, Default, Template)]