release: v0.1.0
This commit is contained in:
parent
6f51441590
commit
18b0b506f3
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@ -42,7 +42,7 @@ jobs:
|
||||
run: go vet ./...
|
||||
|
||||
- name: Staticcheck
|
||||
run: "$(go env GOPATH)/bin/staticcheck" ./...
|
||||
run: '"$(go env GOPATH)/bin/staticcheck" ./...'
|
||||
|
||||
- name: Gofumpt
|
||||
run: |
|
||||
@ -113,7 +113,7 @@ jobs:
|
||||
run: go install golang.org/x/vuln/cmd/govulncheck@v1.1.4
|
||||
|
||||
- name: Run govulncheck
|
||||
run: "$(go env GOPATH)/bin/govulncheck" ./...
|
||||
run: '"$(go env GOPATH)/bin/govulncheck" ./...'
|
||||
|
||||
secrets:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
46
.github/workflows/release.yml
vendored
Normal file
46
.github/workflows/release.yml
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
name: release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v*"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag:
|
||||
description: "Tag to (re)release (e.g. v0.1.0)"
|
||||
required: true
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
goreleaser:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6.0.2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v6.3.0
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
cache: true
|
||||
|
||||
- name: Stash GoReleaser config
|
||||
run: cp .goreleaser.yaml /tmp/.goreleaser.yaml
|
||||
|
||||
- name: Checkout release tag
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
run: git checkout ${{ inputs.tag }}
|
||||
|
||||
- name: GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v6
|
||||
with:
|
||||
distribution: goreleaser
|
||||
version: latest
|
||||
args: release --clean --config /tmp/.goreleaser.yaml
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
36
.goreleaser.yaml
Normal file
36
.goreleaser.yaml
Normal file
@ -0,0 +1,36 @@
|
||||
version: 2
|
||||
|
||||
project_name: discrawl
|
||||
|
||||
changelog:
|
||||
disable: true
|
||||
|
||||
builds:
|
||||
- id: discrawl
|
||||
main: ./cmd/discrawl
|
||||
binary: discrawl
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
ldflags:
|
||||
- -s -w -X github.com/steipete/discrawl/internal/cli.version={{ .Version }}
|
||||
targets:
|
||||
- darwin_amd64
|
||||
- darwin_arm64
|
||||
- linux_amd64
|
||||
- linux_arm64
|
||||
- windows_amd64
|
||||
- windows_arm64
|
||||
|
||||
archives:
|
||||
- ids:
|
||||
- discrawl
|
||||
formats:
|
||||
- tar.gz
|
||||
name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
|
||||
format_overrides:
|
||||
- goos: windows
|
||||
formats:
|
||||
- zip
|
||||
|
||||
checksum:
|
||||
name_template: checksums.txt
|
||||
22
CHANGELOG.md
22
CHANGELOG.md
@ -2,12 +2,18 @@
|
||||
|
||||
All notable changes to `discrawl` will be documented in this file.
|
||||
|
||||
## 0.1.0 - 2026-03-07
|
||||
## 0.1.0 - 2026-03-08
|
||||
|
||||
- initial public release of the `discrawl` CLI
|
||||
- added local SQLite archive, FTS search, raw SQL, sync, tail, status, doctor, members, and channels commands
|
||||
- added OpenClaw/env token resolution and local runtime config
|
||||
- added linting, CI, secret scanning, and coverage enforcement
|
||||
- fixed targeted channel sync to avoid unnecessary guild-wide refresh work
|
||||
- fixed inaccessible channel handling so sync marks and skips `403 Missing Access` channels
|
||||
- fixed empty-channel sync state so full crawls can prove completion for quiet channels
|
||||
- initial public release of `discrawl`
|
||||
- multi-guild Discord crawler with single-guild default UX
|
||||
- local SQLite archive with FTS5 search
|
||||
- commands: `init`, `sync`, `tail`, `search`, `messages`, `mentions`, `sql`, `members`, `channels`, `status`, `doctor`
|
||||
- OpenClaw config reuse plus env-based bot token discovery
|
||||
- resumable full-history sync, live gateway tailing, repair sync loop, targeted channel sync
|
||||
- attachment-text indexing for small text-like uploads
|
||||
- structured user and role mention indexing/querying
|
||||
- empty-message filtering based on real searchable/displayable content instead of raw body only
|
||||
- CI with lint, tests, secret scanning, and `80%+` coverage enforcement
|
||||
- release plumbing via GoReleaser, GitHub Actions, and Homebrew tap packaging
|
||||
- sync correctness fixes for empty channels, inaccessible channels, unknown channels, and large-channel resume behavior
|
||||
- SQLite/FTS performance fixes for backfill throughput and lower write amplification
|
||||
|
||||
98
docs/RELEASING.md
Normal file
98
docs/RELEASING.md
Normal file
@ -0,0 +1,98 @@
|
||||
---
|
||||
summary: "Release checklist for discrawl (GitHub release binaries via GoReleaser + Homebrew tap update)"
|
||||
---
|
||||
|
||||
# Releasing `discrawl`
|
||||
|
||||
Always do all steps below. No partial releases.
|
||||
|
||||
Assumptions:
|
||||
- Repo: `steipete/discrawl`
|
||||
- Binary: `discrawl`
|
||||
- GoReleaser config: `.goreleaser.yaml`
|
||||
- Homebrew tap repo: `~/Projects/homebrew-tap`
|
||||
|
||||
## 0) Prereqs
|
||||
|
||||
- Clean working tree on `main`
|
||||
- Go toolchain from `go.mod`
|
||||
- GitHub CLI authenticated
|
||||
- CI green on `main`
|
||||
|
||||
## 1) Verify build + tests
|
||||
|
||||
```sh
|
||||
go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.5.0 run
|
||||
go test ./... -coverprofile=coverage.out
|
||||
go tool cover -func=coverage.out | tail -n 1
|
||||
go build -o /tmp/discrawl ./cmd/discrawl
|
||||
gh run list -L 5 --branch main
|
||||
```
|
||||
|
||||
Coverage floor: `80%+`
|
||||
|
||||
## 2) Update changelog
|
||||
|
||||
Add a new section in `CHANGELOG.md`.
|
||||
|
||||
Example:
|
||||
|
||||
- `## 0.2.0 - 2026-03-08`
|
||||
|
||||
## 3) Commit, tag, push
|
||||
|
||||
```sh
|
||||
git checkout main
|
||||
git pull --ff-only origin main
|
||||
git commit -am "release: vX.Y.Z"
|
||||
git tag -a vX.Y.Z -m "Release X.Y.Z"
|
||||
git push origin main --tags
|
||||
```
|
||||
|
||||
## 4) Verify GitHub release assets
|
||||
|
||||
The tag push triggers `.github/workflows/release.yml`.
|
||||
|
||||
```sh
|
||||
gh run list -L 5 --workflow release.yml
|
||||
gh release view vX.Y.Z
|
||||
```
|
||||
|
||||
Confirm assets exist for:
|
||||
|
||||
- `darwin_amd64`
|
||||
- `darwin_arm64`
|
||||
- `linux_amd64`
|
||||
- `linux_arm64`
|
||||
- `windows_amd64`
|
||||
- `windows_arm64`
|
||||
|
||||
## 5) Update Homebrew tap
|
||||
|
||||
`discrawl` currently ships a source-build formula in `~/Projects/homebrew-tap/Formula/discrawl.rb`.
|
||||
|
||||
After tagging a real release:
|
||||
|
||||
1. switch the formula URL from the pinned source-commit tarball to the release tag tarball or release binaries
|
||||
2. update `sha256`
|
||||
3. test locally
|
||||
4. commit + push `homebrew-tap`
|
||||
|
||||
Useful commands:
|
||||
|
||||
```sh
|
||||
curl -L -o /tmp/discrawl.tgz https://github.com/steipete/discrawl/archive/refs/tags/vX.Y.Z.tar.gz
|
||||
shasum -a 256 /tmp/discrawl.tgz
|
||||
brew uninstall discrawl || true
|
||||
brew install --build-from-source ./Formula/discrawl.rb
|
||||
brew test discrawl
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- Build-time version stamping comes from `-X github.com/steipete/discrawl/internal/cli.version={{ .Version }}`
|
||||
- If release workflow needs a rerun:
|
||||
|
||||
```sh
|
||||
gh workflow run release.yml -f tag=vX.Y.Z
|
||||
```
|
||||
3
internal/cli/version.go
Normal file
3
internal/cli/version.go
Normal file
@ -0,0 +1,3 @@
|
||||
package cli
|
||||
|
||||
var version = "0.1.0"
|
||||
@ -141,6 +141,33 @@ func TestReadOnlyQueryGuards(t *testing.T) {
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestQueryAndExec(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ctx := context.Background()
|
||||
s, err := Open(ctx, filepath.Join(t.TempDir(), "discrawl.db"))
|
||||
require.NoError(t, err)
|
||||
defer func() { _ = s.Close() }()
|
||||
|
||||
affected, err := s.Exec(ctx, `
|
||||
insert into sync_state(scope, cursor, updated_at)
|
||||
values('scope:test-exec', 'cursor-1', '2026-03-08T00:00:00Z')
|
||||
`)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, int64(1), affected)
|
||||
|
||||
cols, rows, err := s.Query(ctx, `select scope, cursor from sync_state where scope = 'scope:test-exec'`)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, []string{"scope", "cursor"}, cols)
|
||||
require.Equal(t, [][]string{{"scope:test-exec", "cursor-1"}}, rows)
|
||||
|
||||
_, _, err = s.Query(ctx, " ")
|
||||
require.Error(t, err)
|
||||
|
||||
_, err = s.Exec(ctx, " ")
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestUpsertAndDeleteMember(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ package syncer
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"mime"
|
||||
"net/http"
|
||||
@ -188,7 +189,7 @@ func fetchAttachmentText(ctx context.Context, url string) (string, error) {
|
||||
}
|
||||
reader := bufio.NewReader(resp.Body)
|
||||
peek, err := reader.Peek(512)
|
||||
if err != nil && err != io.EOF {
|
||||
if err != nil && !errors.Is(err, io.EOF) {
|
||||
return "", err
|
||||
}
|
||||
if len(peek) != 0 && !isAllowedFetchedContentType(normalizedMediaType(http.DetectContentType(peek))) {
|
||||
|
||||
@ -264,6 +264,16 @@ func TestSyncUsesConfiguredConcurrency(t *testing.T) {
|
||||
require.GreaterOrEqual(t, maxInFlight, 2)
|
||||
}
|
||||
|
||||
func TestSetAttachmentTextEnabled(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
svc := New(&fakeClient{}, nil, nil)
|
||||
require.True(t, svc.attachmentTextEnabled)
|
||||
|
||||
svc.SetAttachmentTextEnabled(false)
|
||||
require.False(t, svc.attachmentTextEnabled)
|
||||
}
|
||||
|
||||
func TestSyncChannelSubsetUsesStoredMetadata(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user