Changelog con Notion
Tags: notion, documentation, git
Published: 2022-12-31 09:12:18

---
title: Changelog con Notion
published: true
date: 2022-12-12 00:00:00 UTC
tags: notion,documentation,git
canonical_url: https://jorge.aguilera.soy/blog/2022/notion-changelog.html
---

"Notion es un software de gestión de proyectos y para tomar notas"

En realidad Notion es un poco más que lo que dice su descripción oficial y se ha vuelto muy popular entre las empresas (y a nivel personal) para mantener la documentación corporativa.

Puedes crear páginas, organizarlas en árbol, tiene muchos emojis (demasiados) disponibles, bases de datos por páginas donde puedes estructurar tus datos como quieras y la página asociada los renderiza, etc.

En este post lo que voy a utilizar es la posibilidad de poder alimentar una base de datos de Notion para que muestre el changelog (el historial de commits) de un repo git

<dl>
<dt>INFO</dt>
<dd>
<p>El concepto de base de datos de Notion es un poco diferente del tradicional (hasta donde he entendido). La idea
es que puedes crear "bases de datos" y renderizar páginas usando los datos de la misma. De esta forma lo que tienes son
muchas bases de datos diferentes, cada una asociada a una "sección", y en la que puedes guardar diferente contenido
(textos, fechas, enlaces, etc) y crear páginas hijas</p>
</dd>
</dl>

## Preparación

Como en el post [anterior](notion-krokio.html) en primer lugar necesitamos crear una connection (obtener un token)

Para este caso además crearemos una base de datos en lugar de una página y le daremos permisos al connection.

Notion crea la base de datos con un par de campos por defecto. Nosotros vamos a usar:

- Name (title)

- Created (date)

- Description (string)

 ![notion bbdd 1](https://jorge.aguilera.soy/images/2022/notion-bbdd-1.png)

## Repositorio Git

La idea es que tendremos un repositorio git en el que iremos subiendo cambios y cada cierto tiempo generaremos una release. Las buenas prácticas lo que nos dicen es que al generar la release creemos un `tag` de tal forma que se pueda saber qué código corresponde con cada release.

Así por ejemplo en un momento dado el historial de nuestro repo sería:

```
$ git log --oneline
f82c632 (HEAD -> master) tres
270b4c9 dos
cd4ed0b (tag: v0.0.1) commit 1
```

En este log vemos que tenemos 3 commits (ya, ya, pero es un ejemplo). El primero lo etiquetamos como release `v0.0.1`y ahora tenemos 2 cambios más y vamos a generar release `v0.0.2`

<dl>
<dt>WARNING</dt>
<dd>
<p>El nombre de los tags para este script le da igual pero es buena práctica seguir una nomenclatura semver</p>
</dd>
</dl>

```
$ git tag -a v0.0.2 -m "esta es la release v0.0.2 con dos cambios"
```

Con lo que ahora tenemos master etiquetado como `v0.0.2`

```
$ git log --oneline
f82c632 (HEAD -> master, tag: v0.0.2) tres
270b4c9 dos
cd4ed0b (tag: v0.0.1) commit 1
```

La idea sería tener una página de Notion asociada a nuestro repositorio donde poder ver de un vistazo que`v0.0.2` fue creada en una fecha, la descripcion con la que se creó así como una lista con los commits que se incluyeron (en nuestro ejemplo serían `270b4c9 dos` y `f82c632 tres`)

## Notion

Una vez que ejecutemos el script nuestra página se actualizará automaticamente como en las imágenes siguientes

(La presentación se puede/debe mejorar pero se deja al lector como ejercicio ;) )

 ![notion bbdd 2](https://jorge.aguilera.soy/images/2022/notion-bbdd-2.png)

 ![notion bbdd 3](https://jorge.aguilera.soy/images/2022/notion-bbdd-3.png)

## Script

El script ejecuta un par de comandos de git para obtener el historial y detalles de los commits realizados en el repo y simplemente usa el api de Notion para crear páginas hijas asociadas a la bbdd que se le configure

```
const fs = require('fs');
const path = require('path');
const {Client} = require("@notionhq/client")

const {execSync} = require("child_process");
const process = require("process");

// Initializing a client
require('dotenv').config();

;(async () => {
    // tag list
    const tagsStr = execSync(
        "git tag -l --sort=-creatordate --format='%(refname:short)'",{
            cwd: process.env.REPO_DIR
        }).toString();
    const tags = tagsStr.split('\n')
    const last = tags[0]
    const prev = tags[1]

    // last tag history
    const history = execSync(
        `git log '${last}'...'${prev}' --pretty=format:"%cs%x09%s%x09%h"`,{
            cwd: process.env.REPO_DIR
        }).toString().split('\n').slice(0, 30);

    // tag message
    const messageStr = execSync(
        `git tag -l --format='%(contents) | %(taggerdate:short) | %(creatordate:short)' ${last}`,{
            cwd: process.env.REPO_DIR
        }).toString().replace(/(\r\n|\n|\r)/gm,'').split('|')

    const tagMsg = messageStr[0];
    const tagDate = (messageStr[1].trim() != 0 ? messageStr[1].trim() : messageStr[2].trim() != 0 ? messageStr[2].trim() : '2001-01-01');

    const blocks = []
    for(h of history){
        blocks.push({
            "type": "paragraph",
            "paragraph": {
                "rich_text": [{
                    "type": "text",
                    "text": {
                        "content": `\n- ${h}\n`,
                        "link": null
                    }
                }]
            }
        })
    }

    const payload = {
        parent: {type: "database_id", database_id: process.env.DB_ID},
        properties: {
            Name: {type: "title", title: [{type: "text", text: {content: tags[0]}}]},
            Created: {type: "date", date: {start: tagDate}},
            Description: {rich_text: [{text: {content: tagMsg,},},],},
        },
        children: blocks
    }

    const notion = new Client({
        auth: process.env.NOTION_TOKEN,
    })

    const newpage = await notion.pages.create(payload);
    console.log(newpage)

})()
```

## Conclusión

La presentación de las páginas se pueden mejorar para incluir enlaces, negritas, etc y hacer más legible el changelog pero es un ejercicio interesante como prueba de integración de procesos externos y Notion para generar contenido de forma automática