Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
name: CI

on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
push:
branches: [main, master]

permissions:
contents: read

concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
test-and-lint:
runs-on: ubuntu-latest
timeout-minutes: 20

strategy:
fail-fast: false
matrix:
go-version: ['1.24.x', '1.25.x']

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go-version }}
cache: true

- name: Verify module graph
if: matrix.go-version == '1.23.x'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Align CI conditionals with Go version matrix

In .github/workflows/ci.yml, the job matrix only runs 1.24.x and 1.25.x, but this step (and the Staticcheck step below) is guarded by if: matrix.go-version == '1.23.x', which can never match. As a result, module graph verification and static analysis are silently skipped on every CI run, so dependency drift and staticcheck-detectable regressions can merge without detection.

Useful? React with 👍 / 👎.

run: |
go mod tidy
git diff --exit-code -- go.mod go.sum

Comment on lines +36 to +41
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this workflow matrix the Go versions are 1.24.x/1.25.x, but this step is gated on matrix.go-version == '1.23.x', so go mod tidy/diff never runs. Update the condition to match one of the matrix versions (or remove the condition) so module tidiness is actually validated.

Copilot uses AI. Check for mistakes.
- name: Format check
run: |
unformatted=$(gofmt -l $(git ls-files '*.go'))
if [ -n "$unformatted" ]; then
echo "These files are not gofmt-formatted:"
echo "$unformatted"
exit 1
fi

- name: Vet
run: go vet ./...

- name: Staticcheck
if: matrix.go-version == '1.23.x'
run: |
go install honnef.co/go/tools/cmd/staticcheck@v0.6.1
TOOLBIN="$(go env GOBIN)"
if [ -z "$TOOLBIN" ]; then
TOOLBIN="$(go env GOPATH)/bin"
fi
"$TOOLBIN/staticcheck" ./...

Comment on lines +54 to +63
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Staticcheck is also gated on matrix.go-version == '1.23.x', which is not present in the matrix. As written, staticcheck will never execute in CI; align the condition with the matrix (or run it unconditionally).

Copilot uses AI. Check for mistakes.
- name: Unit tests
run: go test ./...

- name: Race tests
run: go test -race ./...
91 changes: 91 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
name: Publish

on:
release:
types: [published]

permissions:
contents: read

jobs:
publish-go-module:
if: github.event.release.prerelease == false
runs-on: ubuntu-latest
timeout-minutes: 10

steps:
- name: Checkout release tag
uses: actions/checkout@v4
with:
ref: refs/tags/${{ github.event.release.tag_name }}
fetch-depth: 0

- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: '1.24.x'

- name: Validate release tag format and VERSION match
run: |
TAG="${{ github.event.release.tag_name }}"
case "$TAG" in
v*) ;;
*)
echo "Release tag must start with 'v' (got: $TAG)"
exit 1
;;
esac

TAG_NO_V="${TAG#v}"
VERSION_FILE=$(tr -d '[:space:]' < VERSION)
if ! test "$TAG_NO_V" = "$VERSION_FILE"; then
echo "Release tag version does not match VERSION file"
echo " tag version (without 'v'): $TAG_NO_V"
echo " VERSION file: $VERSION_FILE"
exit 1
fi

- name: Verify release tag is on main
run: |
set -euo pipefail
git fetch origin main:refs/remotes/origin/main
MAIN_SHA=$(git rev-parse origin/main)
if ! test "${GITHUB_SHA}" = "${MAIN_SHA}"; then
echo "Release tag is not at main HEAD; refusing to publish"
echo " tag: ${{ github.event.release.tag_name }}"
echo " tag sha: ${GITHUB_SHA}"
echo " main head: ${MAIN_SHA}"
Comment on lines +48 to +57
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This publish check hard-codes main. Since the repo still references master elsewhere (and CI runs on both), this can fail on repos where the default branch is master. Consider using ${{ github.event.repository.default_branch }} (or checking both branches) when fetching/comparing the default branch head.

Suggested change
- name: Verify release tag is on main
run: |
set -euo pipefail
git fetch origin main:refs/remotes/origin/main
MAIN_SHA=$(git rev-parse origin/main)
if ! test "${GITHUB_SHA}" = "${MAIN_SHA}"; then
echo "Release tag is not at main HEAD; refusing to publish"
echo " tag: ${{ github.event.release.tag_name }}"
echo " tag sha: ${GITHUB_SHA}"
echo " main head: ${MAIN_SHA}"
- name: Verify release tag is on default branch
env:
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
run: |
set -euo pipefail
git fetch origin "${DEFAULT_BRANCH}:refs/remotes/origin/${DEFAULT_BRANCH}"
DEFAULT_BRANCH_SHA=$(git rev-parse "origin/${DEFAULT_BRANCH}")
if ! test "${GITHUB_SHA}" = "${DEFAULT_BRANCH_SHA}"; then
echo "Release tag is not at default branch HEAD; refusing to publish"
echo " tag: ${{ github.event.release.tag_name }}"
echo " tag sha: ${GITHUB_SHA}"
echo " default branch: ${DEFAULT_BRANCH}"
echo " default branch head: ${DEFAULT_BRANCH_SHA}"

Copilot uses AI. Check for mistakes.
exit 1
fi

- name: Trigger Go module proxy indexing
env:
MODULE: github.com/rapidclock/web-octopus
run: |
set -euo pipefail
VERSION="${{ github.event.release.tag_name }}"
URL="https://proxy.golang.org/${MODULE}/@v/${VERSION}.info"
for i in 1 2 3 4 5; do
if curl -fsSL "$URL" >/dev/null; then
exit 0
fi
sleep $((i * 2))
done
echo "failed to fetch module info from proxy after retries"
exit 1

- name: Trigger pkg.go.dev refresh
env:
MODULE: github.com/rapidclock/web-octopus
run: |
set -euo pipefail
VERSION="${{ github.event.release.tag_name }}"
URL="https://pkg.go.dev/fetch/${MODULE}@${VERSION}"
for i in 1 2 3 4 5; do
if curl -fsSL "$URL" >/dev/null; then
exit 0
fi
sleep $((i * 2))
done
echo "failed to trigger pkg.go.dev refresh after retries"
exit 1
13 changes: 0 additions & 13 deletions .travis.yml

This file was deleted.

31 changes: 31 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Changelog

All notable changes to this project are documented in this file.

## [1.3.0] - 2026-02-10

### Added
- Added GitHub Actions CI workflow for pull requests and default-branch pushes with module, formatting, vet, static analysis, test, and race checks.
- Added GitHub Actions publish workflow driven by GitHub Release publication to trigger Go proxy and pkg.go.dev indexing.

### Changed
- Removed legacy Travis CI configuration in favor of GitHub Actions.
- Hardened CI reliability by adding workflow concurrency cancellation, running module/static checks on the primary Go version, and pinning staticcheck.
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changelog states CI runs module/static checks on the primary Go version and pins staticcheck, but the current CI workflow conditions prevent the module/staticcheck steps from running at all. Once CI is fixed, this will be accurate; otherwise consider adjusting this entry to avoid overstating CI coverage.

Suggested change
- Hardened CI reliability by adding workflow concurrency cancellation, running module/static checks on the primary Go version, and pinning staticcheck.
- Hardened CI reliability by adding workflow concurrency cancellation and initial configuration for module/static checks on the primary Go version with a pinned staticcheck version.

Copilot uses AI. Check for mistakes.
- Hardened publish reliability by validating release tag format against `VERSION`, checking out the exact release tag, skipping prereleases, and adding retry logic for Go proxy/pkg.go.dev refresh calls.

## [1.1.0] - 2026-02-10

### Added
- Go module support (`go.mod`) with explicit dependency versions.
- Unit tests for crawler defaults and factory helpers.
- Unit tests for rate-limit validation and timeout setup behavior.
- Unit tests for pipeline helper behavior (link absolution, duplicate filter, timeout propagation).
- Unit test coverage for `adapter.FileWriterAdapter` write behavior.
- Comprehensive README covering installation, architecture, configuration, adapters, testing, and release policy.

### Changed
- Replaced `log.Fatal` behavior in core library paths with non-process-terminating logic (`panic` for invalid setup value and early return for nil or file-open failure paths).
- Improved file adapter open flags to use write-only, create, and truncate semantics for predictable output.

### Notes
- This version focuses on modernization and maintainability without changing the fundamental crawler pipeline design.
Loading