Setting sourcehut repository readme from org-mode files
March 11, 2021 (modified March 22, 2021)
I am moving my code to sourcehut, but I don’t write the projects readmes in plain text or markdown format. I like to write them as org-mode files – given the superiority of the format.
Sourcehut provides an API to set a repositories readme text, as is
explained here. Authorization is done with an OAuth2 bearer token. I
put this token in my encrypted $HOME/.netrc.gpg
, so that I can use
emacs netrc handling code to securly get to the token without leaving
it accessible.
The repository is identified by a unique numerical id. The following
function uses a synchronous request.el
call to fetch and return the id.
(defun tom/srht-repo-id (name) "Return the unique numerical id associated with every sourehut repository." (interactive "sRepo name: ") (let* ((srht (netrc-machine (netrc-parse "~/.netrc.gpg") "repo.git.sr.ht")) (srht-token (netrc-get srht "password")) (oauth2-token (concat "Bearer " srht-token)) (id (assoc-default 'id (assoc-default 'repositoryByName (assoc-default 'data (request-response-data (request "https://git.sr.ht/query" :params `(("query" . ,(concat "query { repositoryByName (name:\"" name "\") { id } }"))) :type "GET" :headers `(("Authorization" . ,oauth2-token)) :parser 'json-read :sync t :timeout 2 :error (cl-function (lambda (&key error-thrown &allow-other-keys) (message "Error %S" error-thrown))) ))))))) (if (called-interactively-p) (message "Id: %S" id) id)))
Once we have the id
we can use the following function to export the
current buffer and set the resulting html as readme for the project.
(defun tom/srht-set-readme (id) "Export the current file to html and set the result as readme for the sourcehut repo identified by ID." (interactive "sRepo id: ") (let* ((srht (netrc-machine (netrc-parse "~/.netrc.gpg") "git.sr.ht")) (srht-token (netrc-get srht "password")) (oauth2-token (concat "Bearer " srht-token)) (readme.html (org-export-as (org-export-get-backend 'html) nil nil t)) (json-object-type 'hash-table) (json-array-type 'list) (json-key-type 'string) (query (make-hash-table)) (variables (make-hash-table))) (puthash "id" id variables) ; the sourcehut repo id (puthash "readme" readme.html variables) (puthash "query" "mutation UpdateRepo($id: Int!, $readme: String!) { updateRepository(id: $id, input: { readme: $readme }) { id } }" query) (puthash "variables" variables query) (request "https://git.sr.ht/query" :type "POST" :data (json-serialize query) :headers `(("Content-Type" . "application/json") ("Authorization" . ,oauth2-token)) :parser 'json-read :complete (cl-function (lambda (&key symbol-status &allow-other-keys) (message "Set: %S" symbol-status))))))
The json handling in both functions is not very sophisticated, but the fastest way for me to get it done as of now – maybe I extract the common pattern and make it a package one of these days.