3 Commits

Author SHA1 Message Date
cbcb1b3778 Index the v3.1.1 release notes
Some checks failed
ci/woodpecker/tag/release Pipeline failed
2026-10-11 01:56:54 +00:00
39052bf47e Write the Audita v3.1.1 release note 2026-10-11 01:55:06 +00:00
7cd5edd650 Resolve annotated tag events before CI delivery 2026-10-11 01:51:44 +00:00
5 changed files with 132 additions and 5 deletions

View File

@@ -20,7 +20,7 @@ steps:
git check-ref-format "refs/tags/$${CI_COMMIT_TAG}"
git fetch origin "refs/tags/$${CI_COMMIT_TAG}:refs/tags/$${CI_COMMIT_TAG}"
tag_commit=$(git rev-parse "refs/tags/$${CI_COMMIT_TAG}^{commit}")
expected_commit=$(printf '%s' "$${CI_COMMIT_SHA}" | tr '[:upper:]' '[:lower:]')
expected_commit=$(git rev-parse --verify "$${CI_COMMIT_SHA}^{commit}")
test "$(printf '%s' "$${tag_commit}" | tr '[:upper:]' '[:lower:]')" = "$${expected_commit}"
git checkout --detach "$${tag_commit}"
test "$(git rev-parse HEAD | tr '[:upper:]' '[:lower:]')" = "$${expected_commit}"
@@ -46,5 +46,5 @@ steps:
"$${bootstrap_dir}/releasekit" ci-deliver \
--repo "$${CI_WORKSPACE}" \
--prepared \
--commit "$${CI_COMMIT_SHA}" \
--commit "$${expected_commit}" \
"$${CI_COMMIT_TAG}"

View File

@@ -104,7 +104,9 @@ Woodpecker runs ReleaseKit's `ci-deliver` command for tags under
- `SHA256SUMS`
Before running Go, the workflow fetches and verifies the event tag, checks it
out detached, and confirms the source tree is clean. It copies the tagged
out detached, and confirms the source tree is clean. It peels the event object
ID to its commit before comparing it with the tag's commit, accepting both
annotated tag objects and commit IDs from Woodpecker. It copies the tagged
`go.mod` and `go.sum` into temporary module metadata outside the checkout. Go
confirms that this configuration selects ReleaseKit, then builds its CLI using
an alternate `-modfile`. The bootstrap executable and temporary files remain
@@ -120,7 +122,7 @@ The resulting executable receives:
"$${bootstrap_dir}/releasekit" ci-deliver \
--repo "$${CI_WORKSPACE}" \
--prepared \
--commit "$${CI_COMMIT_SHA}" \
--commit "$${expected_commit}" \
"$${CI_COMMIT_TAG}"
```

View File

@@ -1,5 +1,6 @@
# Release Notes
- [Audita v3.1.1](v3.1.1.md)
- [Audita v3.1.0](v3.1.0.md)
- [Audita v3.0.1](v3.0.1.md)
- [Audita v3.0.0](v3.0.0.md)

20
docs/releases/v3.1.1.md Normal file
View File

@@ -0,0 +1,20 @@
# Audita v3.1.1
This patch fixes the Woodpecker bootstrap failure that prevented Linux binary
delivery for v3.1.0. Audita's transcript processing and configuration are unchanged.
## Changes
- Resolve Woodpecker's tag-event object ID to its source commit before checking
the tagged checkout and invoking ReleaseKit. Annotated tag events previously
failed a comparison between the tag object and commit, stopping the workflow
before binary builds began.
- Add offline regression coverage for annotated and lightweight tag events,
including rejection of an unrelated source commit.
No configuration, profile, transcript-format, or command-behavior migration is
required from v3.1.0. The Go source-build minimum remains 1.26.0. Linux amd64 and
arm64 binary delivery follows the existing asynchronous
[release procedure](../release.md#binary-delivery).
[COPYRIGHT](https://gitea.maximumdirect.net/eric/audita/src/tag/v3.1.1/COPYRIGHT) | [LICENSE](https://gitea.maximumdirect.net/eric/audita/src/tag/v3.1.1/LICENSE) | [ATTRIBUTION](https://gitea.maximumdirect.net/eric/audita/src/tag/v3.1.1/docs/oss/attribution.md)

View File

@@ -118,7 +118,7 @@ func TestDeliveryWorkflowUsesModuleSelectedReleaseKit(t *testing.T) {
"git fetch origin", "refs/tags/$${CI_COMMIT_TAG}",
"git checkout --detach", "git status --porcelain",
"go list", "-modfile=", "-m", "go build", "$${releasekit_module}/cmd/releasekit",
"ci-deliver", "--repo \"$${CI_WORKSPACE}\"", "--prepared", "--commit \"$${CI_COMMIT_SHA}\"",
"ci-deliver", "--repo \"$${CI_WORKSPACE}\"", "--prepared", "--commit",
"\"$${CI_COMMIT_TAG}\"",
} {
if !strings.Contains(command, fragment) {
@@ -160,6 +160,110 @@ func TestReleaseWrapperStopsWhenBootstrapFails(t *testing.T) {
}
}
func TestDeliveryWorkflowAcceptsTagObjectsAndCommits(t *testing.T) {
var workflow struct {
Steps []struct {
Commands []string `yaml:"commands"`
} `yaml:"steps"`
}
if err := yaml.Unmarshal([]byte(readText(t, "../.woodpecker/release.yml")), &workflow); err != nil {
t.Fatal(err)
}
command := strings.ReplaceAll(workflow.Steps[0].Commands[0], "$${", "${")
root := t.TempDir()
source := filepath.Join(root, "source")
layout := releaseTestLayout{
repo: filepath.Join(root, "checkout"), path: filepath.Join(root, "bin"),
argsLog: filepath.Join(root, "tool-arguments"),
}
for _, directory := range []string{source, layout.path} {
if err := os.MkdirAll(directory, 0755); err != nil {
t.Fatal(err)
}
}
git := func(dir string, args ...string) string {
t.Helper()
cmd := exec.Command("git", args...)
cmd.Dir = dir
output, err := cmd.CombinedOutput()
if err != nil {
t.Fatalf("git %q: %v\n%s", args, err, output)
}
return strings.TrimSpace(string(output))
}
git(source, "init", "-b", "main")
git(source, "config", "user.name", "Release test")
git(source, "config", "user.email", "release-test@example.invalid")
writeReleaseTestFile(t, filepath.Join(source, "go.mod"), []byte(readText(t, "../go.mod")), 0644)
writeReleaseTestFile(t, filepath.Join(source, "go.sum"), nil, 0644)
git(source, "add", "go.mod", "go.sum")
git(source, "commit", "-m", "Initial fixture")
unrelated := git(source, "rev-parse", "HEAD")
git(source, "commit", "--allow-empty", "-m", "Release fixture")
commit := git(source, "rev-parse", "HEAD")
git(source, "tag", "-a", "v3.1.0", "-m", "Annotated release")
git(source, "tag", "v3.1.1")
tagObject := git(source, "rev-parse", "v3.1.0")
git(root, "clone", "--quiet", source, layout.repo)
toolStub := filepath.Join(root, "releasekit-stub")
writeReleaseTestFile(t, toolStub, []byte(`#!/bin/sh
printf '%s\0' "$@" > "$RELEASEKIT_ARGS_LOG"
`), 0755)
writeReleaseTestFile(t, filepath.Join(layout.path, "go"), []byte(`#!/bin/sh
set -eu
case "$1" in
list) exit 0 ;;
build)
while [ "$#" -gt 0 ]; do
if [ "$1" = "-o" ]; then
cp "$RELEASEKIT_STUB" "$2"
exit 0
fi
shift
done ;;
esac
exit 1
`), 0755)
for _, tc := range []struct {
name, tag, eventID string
success bool
}{
{"annotated tag object", "v3.1.0", tagObject, true},
{"annotated tag commit", "v3.1.0", commit, true},
{"lightweight tag commit", "v3.1.1", commit, true},
{"unrelated commit", "v3.1.0", unrelated, false},
} {
t.Run(tc.name, func(t *testing.T) {
if err := os.Remove(layout.argsLog); err != nil && !os.IsNotExist(err) {
t.Fatal(err)
}
cmd := exec.Command("sh", "-c", command)
cmd.Dir = layout.repo
cmd.Env = layout.environment(map[string]string{
"CI_WORKSPACE": layout.repo, "CI_COMMIT_TAG": tc.tag, "CI_COMMIT_SHA": tc.eventID,
"RELEASEKIT_ARGS_LOG": layout.argsLog, "RELEASEKIT_STUB": toolStub,
})
output, err := cmd.CombinedOutput()
if tc.success {
if err != nil {
t.Fatalf("workflow failed: %v\n%s", err, output)
}
want := []string{"ci-deliver", "--repo", layout.repo, "--prepared", "--commit", commit, tc.tag}
if got := readNULArguments(t, layout.argsLog); !reflect.DeepEqual(got, want) {
t.Fatalf("delivery arguments = %q, want %q", got, want)
}
} else {
if err == nil {
t.Fatal("workflow accepted an unrelated commit")
}
if _, err := os.Stat(layout.argsLog); !os.IsNotExist(err) {
t.Fatalf("delivery ran after mismatched event; stat error = %v", err)
}
}
})
}
}
func TestReleaseKitProfileDeclaresProductAndDeliverySettings(t *testing.T) {
data, err := os.ReadFile("../releasekit.json")
if err != nil {