docs: corrige comando sem -m, dono do repo Gitea, descricao e README

- spec: uso correto e' 'python -m scripts.publish', nao o caminho direto do
  arquivo (imports absolutos quebram sem -m); ajusta texto do --dry-run pra
  descrever o que ele realmente imprime (arvore + URLs, nao payload
  completo); deixa explicito que a URL em Referencias e' link Markdown.
- plan: dono real do repo Gitea e' ai-bot/cursos, nao ia-bot/cursos.
- pyproject.toml: descricao real do projeto.
- README.md novo: o que e' o repo, estrutura, variaveis de .env, comando de uso.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-30 21:22:25 -03:00
parent 3ff7f5992a
commit 3be955fe5a
4 changed files with 58 additions and 12 deletions

40
README.md Normal file
View File

@@ -0,0 +1,40 @@
# cursos
Pipeline + conteúdo de cursos para publicar em cursos.overia.com.br
(LearnHouse), um curso por tecnologia.
## Estrutura
```
courses/<slug>/course.json
courses/<slug>/<NN> - <Nome do Capítulo>/<NN> - <Nome da Aula>.md
```
`course.json` guarda os metadados do curso (`name`, `description`, `about`,
`public`). Nome de capítulo/aula vem do nome da pasta/arquivo, prefixado por
um número de ordem (ex: `01 - Introdução`, `02 - Instalando o Python.md`).
## `.env`
```
LEARNHOUSE_API_TOKEN=
LEARNHOUSE_BASE_URL=
LEARNHOUSE_ORG_ID=
LEARNHOUSE_ORG_SLUG=
GITEA_RAW_BASE=
```
`GITEA_RAW_BASE` é a raiz raw do repo no Gitea (ex:
`https://git.xenserver.com.br/ai-bot/cursos/raw/branch/main/courses`), usada
pra montar a URL de cada aula Markdown.
## Uso
```bash
uv run python -m scripts.publish <slug> [--dry-run|--publish]
```
- `--dry-run`: mostra a árvore de curso/capítulos/aulas e as URLs geradas,
sem chamar a API.
- `--publish`: além de criar/atualizar o curso, marca atividades e curso
como publicados. Sem essa flag, tudo fica em rascunho.

View File

@@ -646,11 +646,11 @@ from scripts.publish import build_markdown_url, publish_course
def test_build_markdown_url_encodes_spaces_and_accents():
url = build_markdown_url(
"https://git.xenserver.com.br/ia-bot/cursos/raw/branch/main/courses",
"https://git.xenserver.com.br/ai-bot/cursos/raw/branch/main/courses",
Path("python/01 - Introdução/01 - O que é Python.md"),
)
assert url == (
"https://git.xenserver.com.br/ia-bot/cursos/raw/branch/main/courses/"
"https://git.xenserver.com.br/ai-bot/cursos/raw/branch/main/courses/"
"python/01%20-%20Introdu%C3%A7%C3%A3o/01%20-%20O%20que%20%C3%A9%20Python.md"
)
@@ -1153,19 +1153,19 @@ publicar este repositório em `git.xenserver.com.br`. **Confirmar com o
usuário antes do push**, conforme as regras do projeto (nunca fazer push sem
confirmação explícita).
Anotar a URL final do repo (ex: `git.xenserver.com.br/ia-bot/cursos`) e o
Anotar a URL final do repo (ex: `git.xenserver.com.br/ai-bot/cursos`) e o
nome do branch padrão (provavelmente `main`).
- [ ] **Step 2: Preencher `GITEA_RAW_BASE` no `.env`**
Formato: `https://<host>/<owner>/<repo>/raw/branch/<branch>/courses`
Exemplo: `https://git.xenserver.com.br/ia-bot/cursos/raw/branch/main/courses`
Exemplo: `https://git.xenserver.com.br/ai-bot/cursos/raw/branch/main/courses`
- [ ] **Step 3: Conferir que o raw URL de uma aula responde**
```bash
curl -sI "https://git.xenserver.com.br/ia-bot/cursos/raw/branch/main/courses/python/01%20-%20Introdu%C3%A7%C3%A3o/01%20-%20O%20que%20%C3%A9%20Python.md"
curl -sI "https://git.xenserver.com.br/ai-bot/cursos/raw/branch/main/courses/python/01%20-%20Introdu%C3%A7%C3%A3o/01%20-%20O%20que%20%C3%A9%20Python.md"
```
Expected: `HTTP/2 200`

View File

@@ -40,8 +40,9 @@ depois de dominar esse tópico.
## 📚 Referências
- <Nome do recurso gratuito>, <URL da lista-base> — única fonte citada por
capítulo (sem fontes adicionais na v1).
- [<Nome do recurso gratuito>](<URL da lista-base>) — a URL deve ser um link
Markdown clicável, não texto solto; única fonte citada por capítulo (sem
fontes adicionais na v1).
```
Esse bloco vai no final do **último arquivo `.md` do capítulo** — não é uma
@@ -131,9 +132,13 @@ na org (`GET /courses/org_slug/overia/...`) — se existir, atualiza em vez de
duplicar. Chapters/activities dentro de um curso novo são sempre criados do
zero (não há update parcial na v1).
Uso: `python scripts/publish.py <slug> [--publish] [--dry-run]`.
`--dry-run` mostra os payloads sem chamar a API — serve de auto-teste rodável
(regra ponytail: lógica não-trivial não fica sem verificação).
Uso: `uv run python -m scripts.publish <slug> [--publish] [--dry-run]` (precisa
ser `-m scripts.publish`, não o caminho direto do arquivo — o módulo usa
imports absolutos, `from scripts.env import ...`, que só resolvem rodando
como pacote).
`--dry-run` mostra a árvore de curso/capítulos/aulas e as URLs geradas, sem
chamar a API — serve de auto-teste rodável (regra ponytail: lógica
não-trivial não fica sem verificação).
Erros da API (4xx/5xx) interrompem o script com a resposta impressa — sem
retry silencioso, sem fallback que mascare falha de publicação.
@@ -156,7 +161,8 @@ descrito acima (fonte: learnpython.org).
1. Implementar `scripts/publish.py` + `learnhouse_client.py`.
2. Escrever o curso de Python completo (conteúdo original, PT-BR).
3. Publicar via `publish.py --dry-run` → revisar payload → publicar de fato
3. Publicar via `python -m scripts.publish --dry-run` → revisar a árvore
gerada → publicar de fato
(sem `--publish` inicialmente, ficando como rascunho na plataforma pra
revisão visual antes de tornar público).
4. Validar no dashboard (cursos.overia.com.br/dash) e ajustar o pipeline se

View File

@@ -1,7 +1,7 @@
[project]
name = "cursos-overia"
version = "0.1.0"
description = "Add your description here"
description = "Pipeline de publicação de cursos para cursos.overia.com.br"
authors = [
{ name = "ia-bot", email = "ia-bot@xenserver.com.br" }
]