Skip to content

Commit 63b8e36

Browse files
committed
Fix release binary swap and plt build on image-only playlists
Release pipeline shipped the placeholder dummy binary instead of the real bazel-built one. goreleaser v2 appends a CPU microarchitecture level to each output directory (vbs_darwin_arm64_v8.0, vbs_linux_amd64_v1, ...), but the post-hook copied bazel binaries into the un-suffixed vbs_<os>_<arch> dirs, so goreleaser archived the dummy. - goreleaser-post-hook.ps1: match goreleaser dist dirs by os/arch prefix and swap per target (goreleaser passes os/arch and runs the hook in parallel). - dummy.go: the placeholder main now prints an error and exits 1 instead of exiting 0 silently, so a failed swap is detectable. - .goreleaser.yml: migrate deprecated brews to homebrew_casks; add a postflight xattr hook to strip macOS quarantine from the unsigned binary. plt build aborted on image-only playlists with "unknown language id 0" because no item carried a video Location to infer the language from, though images need no language. - resolveLanguage: treat id 0 (no language determined) as non-fatal. - plt_build.go: enforce a language at download time, where it is actually used.
1 parent 95188dd commit 63b8e36

6 files changed

Lines changed: 76 additions & 17 deletions

File tree

.goreleaser.yml

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ builds:
1313
- windows_amd64
1414
binary: vbs
1515
hooks:
16-
post: pwsh goreleaser-post-hook.ps1
16+
post: pwsh goreleaser-post-hook.ps1 {{ .Os }} {{ .Arch }}
1717

1818
checksum:
1919
name_template: 'checksums.txt'
@@ -27,7 +27,7 @@ announce:
2727
message_template: '{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ .ReleaseURL }} or brew upgrade {{ .ProjectName }}'
2828
author: 'GoReleaser'
2929

30-
brews:
30+
homebrew_casks:
3131
- repository:
3232
owner: kindlyops
3333
name: homebrew-tap
@@ -59,15 +59,14 @@ brews:
5959
# Default is empty.
6060
description: "vbs helps work with video broadcast files and streams."
6161

62-
# So you can `brew test` your formula.
63-
# Default is empty.
64-
test: |
65-
system "#{bin}/vbs --version"
66-
67-
# Custom install script for brew.
68-
# Default is 'bin.install "program"'.
69-
install: |
70-
bin.install "vbs"
62+
# vbs ships unsigned, so macOS quarantines the downloaded binary and refuses
63+
# to run it ("vbs is damaged"). Strip the quarantine attribute on install.
64+
hooks:
65+
post:
66+
install: |
67+
if OS.mac?
68+
system_command "/usr/bin/xattr", args: ["-dr", "com.apple.quarantine", "#{staged_path}/vbs"]
69+
end
7170
7271
scoops:
7372
- # Template for the url which is determined by the given Token (github or gitlab)

cmd/plt_build.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,11 @@ func (ctx *buildContext) cutCues(
312312
// resolveMedia downloads and caches the rendition for a location, memoizing by
313313
// query URL so a location referenced by several items is fetched once.
314314
func (ctx *buildContext) resolveMedia(loc *Location) (resolvedMedia, error) {
315+
if ctx.langCode == "" {
316+
return resolvedMedia{}, fmt.Errorf(
317+
"unknown language id %d; set it explicitly with --lang", ctx.langID)
318+
}
319+
315320
endpoint, err := buildMediaURL(ctx.base, ctx.langCode, loc)
316321
if err != nil {
317322
return resolvedMedia{}, err

cmd/plt_helpers.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,19 @@ func ticksToSeconds(ticks int64) float64 {
3535
}
3636

3737
// resolveLanguage returns the written-language code for a MepsLanguage ID.
38-
// A non-empty override always wins; otherwise the embedded map is consulted
39-
// and an unmapped ID is a fatal error naming the override flag.
38+
// A non-empty override always wins. An ID of 0 means no located item dictated a
39+
// language (e.g. an image-only playlist), which is not an error here: an empty
40+
// code is returned and any download that genuinely needs a language enforces it
41+
// at fetch time. A non-zero, unmapped ID is a fatal error naming the flag.
4042
func resolveLanguage(id int, override string) (string, error) {
4143
if override != "" {
4244
return override, nil
4345
}
4446

47+
if id == 0 {
48+
return "", nil
49+
}
50+
4551
if code, ok := languageNames[id]; ok {
4652
return code, nil
4753
}

cmd/plt_helpers_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ func TestResolveLanguage(t *testing.T) {
5454
{"override wins over known", 420, "ESL", "ESL", false},
5555
{"override fills unknown", 999, "FOO", "FOO", false},
5656
{"unknown id is fatal", 999, "", "", true},
57+
{"id 0 is not fatal", 0, "", "", false},
58+
{"override wins over id 0", 0, "ASL", "ASL", false},
5759
}
5860

5961
for _, tc := range cases {

dummy.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,27 @@
11
//go:build neverbuild
22
// +build neverbuild
33

4+
// This file is the placeholder main that goreleaser compiles (see
5+
// .goreleaser.yml `main: dummy.go`). The real binary is built by bazel and
6+
// swapped into goreleaser's dist directory by goreleaser-post-hook.ps1. The
7+
// neverbuild constraint keeps `go build ./...`, `go test`, and bazel from
8+
// picking up this empty main; goreleaser bypasses the constraint because it
9+
// names the file explicitly on the `go build` command line.
10+
//
11+
// If you are seeing this message at runtime, the bazel binary was NOT swapped
12+
// in during release and the placeholder shipped instead. That is a packaging
13+
// bug, not a usable build of vbs.
414
package main
515

16+
import (
17+
"fmt"
18+
"os"
19+
)
20+
621
func main() {
22+
fmt.Fprintln(os.Stderr,
23+
"vbs: this is the placeholder build; the real binary was not packaged "+
24+
"during release. Please report this at "+
25+
"https://github.com/kindlyops/vbs/issues")
26+
os.Exit(1)
727
}

goreleaser-post-hook.ps1

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,36 @@
11
#!/usr/bin/env pwsh
22

3-
Write-Output "moving bazel outputs to goreleaser dist directory for packaging..."
3+
# goreleaser compiles the placeholder dummy.go (see .goreleaser.yml). This hook
4+
# replaces one target's placeholder binary in goreleaser's dist directory with
5+
# the real binary that bazel built under bazel-bin/bdist, before goreleaser
6+
# archives it. goreleaser runs the post hook once per target in parallel and
7+
# passes that target's os and arch, so each invocation swaps only its own
8+
# binary (copying every binary on every invocation would race).
9+
#
10+
# goreleaser v2 appends a CPU microarchitecture level to each output directory
11+
# (e.g. vbs_darwin_arm64_v8.0, vbs_linux_amd64_v1), while bazel emits plain
12+
# vbs_<os>_<arch> directories. Match by os/arch prefix so the swap keeps working
13+
# regardless of which microarchitecture suffix goreleaser chooses.
414

5-
if (-Not (Test-Path "dist")) {
6-
New-Item -Force -Path (Get-Location).Path -Name "dist" -ItemType "directory"
15+
param(
16+
[Parameter(Mandatory = $true)][string]$Os,
17+
[Parameter(Mandatory = $true)][string]$Arch
18+
)
19+
20+
$ErrorActionPreference = "Stop"
21+
22+
$name = "vbs_${Os}_${Arch}"
23+
$srcDir = Join-Path (Resolve-Path "bazel-bin/bdist") $name
24+
if (-Not (Test-Path $srcDir)) {
25+
throw "no bazel output at $srcDir for target $Os/$Arch"
726
}
827

9-
Copy-Item (Resolve-Path "bazel-bin/bdist/*") -Destination (Resolve-Path "dist") -Recurse -Force
28+
$destDirs = Get-ChildItem -Path "dist" -Directory -Filter "$name*"
29+
if ($destDirs.Count -eq 0) {
30+
throw "no goreleaser dist directory matches $name; cannot swap in the bazel binary"
31+
}
32+
33+
foreach ($destDir in $destDirs) {
34+
Copy-Item -Path (Join-Path $srcDir "*") -Destination $destDir.FullName -Recurse -Force
35+
Write-Output "swapped bazel binary $name -> dist/$($destDir.Name)"
36+
}

0 commit comments

Comments
 (0)