2026-01-28 17:59:02 +00:00
|
|
|
// Package build provides project type detection and cross-compilation for the Core build system.
|
|
|
|
|
package build
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"crypto/sha256"
|
|
|
|
|
"encoding/hex"
|
|
|
|
|
"fmt"
|
|
|
|
|
"io"
|
|
|
|
|
"path/filepath"
|
2026-02-04 14:23:46 +00:00
|
|
|
|
|
|
|
|
io_interface "github.com/host-uk/core/pkg/io"
|
2026-01-28 17:59:02 +00:00
|
|
|
"sort"
|
|
|
|
|
"strings"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// Checksum computes SHA256 for an artifact and returns the artifact with the Checksum field filled.
|
2026-02-04 14:23:46 +00:00
|
|
|
func Checksum(fs io_interface.Medium, artifact Artifact) (Artifact, error) {
|
2026-01-28 17:59:02 +00:00
|
|
|
if artifact.Path == "" {
|
|
|
|
|
return Artifact{}, fmt.Errorf("build.Checksum: artifact path is empty")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Open the file
|
2026-02-04 14:23:46 +00:00
|
|
|
file, err := fs.Open(artifact.Path)
|
2026-01-28 17:59:02 +00:00
|
|
|
if err != nil {
|
|
|
|
|
return Artifact{}, fmt.Errorf("build.Checksum: failed to open file: %w", err)
|
|
|
|
|
}
|
feat: infrastructure packages and lint cleanup (#281)
* ci: consolidate duplicate workflows and merge CodeQL configs
Remove 17 duplicate workflow files that were split copies of the
combined originals. Each family (CI, CodeQL, Coverage, PR Build,
Alpha Release) had the same job duplicated across separate
push/pull_request/schedule/manual trigger files.
Merge codeql.yml and codescan.yml into a single codeql.yml with
a language matrix covering go, javascript-typescript, python,
and actions — matching the previous default setup coverage.
Remaining workflows (one per family):
- ci.yml (push + PR + manual)
- codeql.yml (push + PR + schedule, all languages)
- coverage.yml (push + PR + manual)
- alpha-release.yml (push + manual)
- pr-build.yml (PR + manual)
- release.yml (tag push)
- agent-verify.yml, auto-label.yml, auto-project.yml
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add collect, config, crypt, plugin packages and fix all lint issues
Add four new infrastructure packages with CLI commands:
- pkg/config: layered configuration (defaults → file → env → flags)
- pkg/crypt: crypto primitives (Argon2id, AES-GCM, ChaCha20, HMAC, checksums)
- pkg/plugin: plugin system with GitHub-based install/update/remove
- pkg/collect: collection subsystem (GitHub, BitcoinTalk, market, papers, excavate)
Fix all golangci-lint issues across the entire codebase (~100 errcheck,
staticcheck SA1012/SA1019/ST1005, unused, ineffassign fixes) so that
`core go qa` passes with 0 issues.
Closes #167, #168, #170, #250, #251, #252, #253, #254, #255, #256
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 11:34:43 +00:00
|
|
|
defer func() { _ = file.Close() }()
|
2026-01-28 17:59:02 +00:00
|
|
|
|
|
|
|
|
// Compute SHA256 hash
|
|
|
|
|
hasher := sha256.New()
|
|
|
|
|
if _, err := io.Copy(hasher, file); err != nil {
|
|
|
|
|
return Artifact{}, fmt.Errorf("build.Checksum: failed to hash file: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
checksum := hex.EncodeToString(hasher.Sum(nil))
|
|
|
|
|
|
|
|
|
|
return Artifact{
|
|
|
|
|
Path: artifact.Path,
|
|
|
|
|
OS: artifact.OS,
|
|
|
|
|
Arch: artifact.Arch,
|
|
|
|
|
Checksum: checksum,
|
|
|
|
|
}, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ChecksumAll computes checksums for all artifacts.
|
|
|
|
|
// Returns a slice of artifacts with their Checksum fields filled.
|
2026-02-04 14:23:46 +00:00
|
|
|
func ChecksumAll(fs io_interface.Medium, artifacts []Artifact) ([]Artifact, error) {
|
2026-01-28 17:59:02 +00:00
|
|
|
if len(artifacts) == 0 {
|
|
|
|
|
return nil, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var checksummed []Artifact
|
|
|
|
|
for _, artifact := range artifacts {
|
2026-02-04 14:23:46 +00:00
|
|
|
cs, err := Checksum(fs, artifact)
|
2026-01-28 17:59:02 +00:00
|
|
|
if err != nil {
|
|
|
|
|
return checksummed, fmt.Errorf("build.ChecksumAll: failed to checksum %s: %w", artifact.Path, err)
|
|
|
|
|
}
|
|
|
|
|
checksummed = append(checksummed, cs)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return checksummed, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// WriteChecksumFile writes a CHECKSUMS.txt file with the format:
|
|
|
|
|
//
|
|
|
|
|
// sha256hash filename1
|
|
|
|
|
// sha256hash filename2
|
|
|
|
|
//
|
|
|
|
|
// The artifacts should have their Checksum fields filled (call ChecksumAll first).
|
|
|
|
|
// Filenames are relative to the output directory (just the basename).
|
2026-02-04 14:23:46 +00:00
|
|
|
func WriteChecksumFile(fs io_interface.Medium, artifacts []Artifact, path string) error {
|
2026-01-28 17:59:02 +00:00
|
|
|
if len(artifacts) == 0 {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Build the content
|
|
|
|
|
var lines []string
|
|
|
|
|
for _, artifact := range artifacts {
|
|
|
|
|
if artifact.Checksum == "" {
|
|
|
|
|
return fmt.Errorf("build.WriteChecksumFile: artifact %s has no checksum", artifact.Path)
|
|
|
|
|
}
|
|
|
|
|
filename := filepath.Base(artifact.Path)
|
|
|
|
|
lines = append(lines, fmt.Sprintf("%s %s", artifact.Checksum, filename))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Sort lines for consistent output
|
|
|
|
|
sort.Strings(lines)
|
|
|
|
|
|
|
|
|
|
content := strings.Join(lines, "\n") + "\n"
|
|
|
|
|
|
2026-02-04 14:23:46 +00:00
|
|
|
// Write the file using the medium (which handles directory creation in Write)
|
|
|
|
|
if err := fs.Write(path, content); err != nil {
|
2026-01-28 17:59:02 +00:00
|
|
|
return fmt.Errorf("build.WriteChecksumFile: failed to write file: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|