···6868**Usage:**
6969```bash
7070# Linux/macOS
7171-curl -fsSL https://atcr.io/install.sh | bash
7171+curl -fsSL https://atcr.io/static/install.sh | bash
72727373# Windows (PowerShell)
7474iwr -useb https://atcr.io/install.ps1 | iex
···113113sudo mv $(go env GOPATH)/bin/credential-helper /usr/local/bin/docker-credential-atcr
114114```
115115116116-**Note:** This requires Go 1.23+ and compiles locally.
116116+**Note:** This requires Go 1.26+ and compiles locally.
117117118118## Release Process
119119···138138 - Visit: https://github.com/atcr-io/atcr/releases
139139 - Test install script:
140140 ```bash
141141- ATCR_VERSION=v1.0.0 curl -fsSL https://atcr.io/install.sh | bash
141141+ ATCR_VERSION=v1.0.0 curl -fsSL https://atcr.io/static/install.sh | bash
142142 docker-credential-atcr version
143143 ```
144144···266266 # Clean install in fresh environment
267267 docker run --rm -it ubuntu:latest bash
268268 apt update && apt install -y curl
269269- curl -fsSL https://atcr.io/install.sh | bash
269269+ curl -fsSL https://atcr.io/static/install.sh | bash
270270 ```
2712712722722. **Test Docker integration:**
+43
pkg/appview/middleware/goimport.go
···11+package middleware
22+33+import (
44+ "fmt"
55+ "html"
66+ "net/http"
77+)
88+99+// GoImport serves the `<meta name="go-import">` tag required by `go install` /
1010+// `go get` to resolve the vanity path `atcr.io/...` to the source repository.
1111+//
1212+// Go tooling requests `https://atcr.io/<subpath>?go-get=1` and expects an HTML
1313+// document with a meta tag of the form:
1414+//
1515+// <meta name="go-import" content="<root> <vcs> <repo-url>">
1616+//
1717+// The meta tag must be present on every subpath under the module root, so this
1818+// runs as middleware at the top of the chain and short-circuits any request
1919+// carrying `?go-get=1`.
2020+func GoImport(modulePath, repoURL string) func(http.Handler) http.Handler {
2121+ body := fmt.Sprintf(
2222+ `<!DOCTYPE html><html><head><meta name="go-import" content="%s git %s"><meta name="go-source" content="%s %s %s/tree/main{/dir} %s/tree/main{/dir}/{file}#L{line}"></head><body>go get %s</body></html>`,
2323+ html.EscapeString(modulePath),
2424+ html.EscapeString(repoURL),
2525+ html.EscapeString(modulePath),
2626+ html.EscapeString(repoURL),
2727+ html.EscapeString(repoURL),
2828+ html.EscapeString(repoURL),
2929+ html.EscapeString(modulePath),
3030+ )
3131+3232+ return func(next http.Handler) http.Handler {
3333+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
3434+ if r.URL.Query().Get("go-get") != "1" {
3535+ next.ServeHTTP(w, r)
3636+ return
3737+ }
3838+ w.Header().Set("Content-Type", "text/html; charset=utf-8")
3939+ w.Header().Set("Cache-Control", "public, max-age=300")
4040+ _, _ = w.Write([]byte(body))
4141+ })
4242+ }
4343+}