Como publicar um writeup

Este site é gerado a partir de arquivos Markdown guardados neste repositório no GitHub. Não existe painel de administração: publicar um writeup é criar (ou editar) arquivos, enviar pro GitHub e deixar a automação (GitHub Actions) cuidar do resto. Qualquer pessoa com acesso ao repositório pode seguir este guia.

1. Preparar o ambiente local

Clone o repositório (só precisa fazer isso uma vez):

git clone git@github.com:rniedson/writeups_ctf.git
cd writeups_ctf
npm install

Antes de começar um writeup novo, crie uma branch a partir da main atualizada:

git checkout main
git pull
git checkout -b writeup/nome-do-desafio

2. Duplicar o modelo

Os arquivos de modelo ficam em templates/writeup/pt.md, es.md, en.md e uma pasta imagens/ vazia. Copie essa pasta inteira para dentro de src/content/writeups/, com o nome do evento e do desafio em minúsculas e sem espaços (o caminho vira parte da URL):

mkdir -p "src/content/writeups/<evento-slug>/<desafio-slug>"
cp templates/writeup/pt.md templates/writeup/es.md templates/writeup/en.md \
   "src/content/writeups/<evento-slug>/<desafio-slug>/"
cp -r templates/writeup/imagens "src/content/writeups/<evento-slug>/<desafio-slug>/"

Você não precisa preencher os três idiomas de uma vez — pode publicar só pt.md agora e traduzir depois. Enquanto uma tradução não existir, o site mostra a versão em português nessa rota, com um aviso de “tradução pendente”.

3. Preencher o frontmatter

Cada arquivo .md começa com um bloco de metadados entre ---. O modelo já vem com um comentário explicando cada campo — os principais são:

CampoO que é
titleTítulo exibido no site
descriptionResumo de 1-2 frases (aparece no card e ao compartilhar)
eventNome do CTF/plataforma — vira o filtro “Organizadora”
categoryweb, pwn, reverse, crypto, forensics, misc, osint ou hardware
subcategoryClasse de vulnerabilidade dentro da categoria — texto livre, ex.: IDOR, XXE, SSTI, JWT (opcional, vira o filtro “Subcategoria”, agrupado por categoria)
difficultyeasy, medium ou hard (opcional)
tagsLista livre de temas — viram o filtro “Tema”
pubDateData de publicação (AAAA-MM-DD)
authorSeu nome — campo obrigatório, aparece no filtro “Autor”
drafttrue esconde o writeup do site até você trocar pra false

Frontmatter inválido quebra a build

Se category tiver um valor fora da lista, ou faltar um campo obrigatório como author, o build falha — tanto localmente (npm run check) quanto no GitHub Actions do pull request. É assim que o site garante que nenhum writeup mal formatado vá pro ar.

4. Escrever o conteúdo

Abaixo do frontmatter é Markdown normal. Alguns recursos que o site já suporta:

  • Callouts> [!NOTE], [!TIP], [!IMPORTANT], [!WARNING] ou [!CAUTION] na primeira linha do bloco de citação, com título opcional ([!TIP/Um título aqui]).
  • Blocos de código com linguagem (```json, ```bash, etc.) ganham realce de sintaxe, numeração de linha e botão de copiar automaticamente.
  • Imagens vão na pasta imagens/ ao lado do .md e são referenciadas com caminho relativo — ![texto alternativo](./imagens/nome.png) — o Astro otimiza o arquivo no build.
  • Arquivos para download (scripts de exploit, por exemplo) vão em public/writeups/<evento>/<desafio>/ e são referenciados com caminho absoluto a partir da raiz do site: [baixar solve.py](/writeups/<evento>/<desafio>/solve.py).

5. Testar localmente (recomendado)

npm run dev

Abra http://localhost:4321/pt/writeups/<evento-slug>/<desafio-slug>/ e confira o resultado. Rode também a validação completa antes de enviar:

npm run check
npm run format
npm run build

npm run format corrige a formatação automaticamente (Prettier); os outros dois só checam.

6. Commit, push e pull request

git add src/content/writeups/<evento-slug>/<desafio-slug>/
git commit -m "Add writeup: <nome do desafio>"
git push -u origin writeup/nome-do-desafio

Abra um pull request no GitHub da sua branch para main. O workflow de CI roda astro check, format:check e build automaticamente — se algo passar batido localmente mas quebrar lá, o PR mostra exatamente o quê.

7. Merge e publicação automática

Depois que o PR for aprovado e mesclado (merge) em main, o workflow Deploy to GitHub Pages dispara sozinho e publica o site atualizado — sem nenhum passo manual. Acompanhe pela aba Actions do repositório; em geral leva menos de um minuto.


Dúvidas sobre a estrutura do projeto? Veja o README.md do repositório, que tem mais detalhes técnicos sobre arquitetura, deploy e política de publicação responsável.