diff --git a/.github/workflows/develop.yml b/.github/workflows/develop.yml
new file mode 100644
index 0000000..a9e2a54
--- /dev/null
+++ b/.github/workflows/develop.yml
@@ -0,0 +1,174 @@
+name: Develop Build
+
+on:
+ push:
+ branches:
+ - develop
+
+permissions:
+ contents: read
+ id-token: write # required for Workload Identity Federation (signing only)
+
+jobs:
+ build:
+ name: Build QC artifacts
+ runs-on: ubuntu-latest
+ timeout-minutes: 60
+
+ steps:
+ - name: Check out repository
+ uses: actions/checkout@v5
+ with:
+ fetch-depth: 0
+
+ - name: Set up Go
+ uses: actions/setup-go@v6
+ with:
+ go-version-file: go.mod
+ cache: true
+
+ - name: Run GoReleaser (all platforms, unsigned)
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: |
+ docker run --rm \
+ -v "${PWD}:/workspace" \
+ -w /workspace \
+ -e GITHUB_TOKEN \
+ ghcr.io/goreleaser/goreleaser-cross:v1.25-v2.12.7 \
+ release --snapshot --config .goreleaser/config-qc.yaml --clean --parallelism 2
+
+ - name: Upload build artifacts
+ uses: actions/upload-artifact@v4
+ with:
+ name: qc-artifacts-${{ github.run_number }}
+ if-no-files-found: error
+ path: |
+ dist/*.tar.gz
+ dist/*.zip
+ dist/checksums.txt
+ dist/artifacts.json
+ dist/metadata.json
+
+ sign-macos:
+ name: Sign macOS artifacts
+ runs-on: macos-latest
+ needs: build
+ timeout-minutes: 30
+
+ steps:
+ - name: Check out repository
+ uses: actions/checkout@v5
+
+ - name: Check for Apple signing secrets
+ id: secrets_check
+ env:
+ APPLE_CERT_P12: ${{ secrets.APPLE_CERT_P12 }}
+ run: |
+ if [ -n "$APPLE_CERT_P12" ]; then
+ echo "has_signing_cert=true" >> "$GITHUB_OUTPUT"
+ else
+ echo "has_signing_cert=false" >> "$GITHUB_OUTPUT"
+ echo "::warning::APPLE_CERT_P12 not configured — skipping Apple code signing."
+ fi
+
+ - name: Import Apple certificate
+ if: ${{ steps.secrets_check.outputs.has_signing_cert == 'true' }}
+ env:
+ APPLE_CERT_P12: ${{ secrets.APPLE_CERT_P12 }}
+ APPLE_CERT_PASSWORD: ${{ secrets.APPLE_CERT_PASSWORD }}
+ KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
+ run: |
+ set -e
+ for var_name in APPLE_CERT_PASSWORD KEYCHAIN_PASSWORD; do
+ if [ -z "${!var_name}" ]; then
+ echo "::error::$var_name is required when APPLE_CERT_P12 is configured."
+ exit 1
+ fi
+ done
+
+ printf '%s' "$APPLE_CERT_P12" | base64 -D > cert.p12
+
+ KEYCHAIN_PATH="$RUNNER_TEMP/build.keychain-db"
+ security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
+ security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH"
+ security import cert.p12 -k "$KEYCHAIN_PATH" -P "$APPLE_CERT_PASSWORD" -T /usr/bin/codesign
+ security set-key-partition-list -S apple-tool:,apple: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
+ security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
+ security list-keychains -d user -s "$KEYCHAIN_PATH" $(security list-keychains -d user | tr -d '"' | xargs)
+
+ - name: Download build artifacts
+ uses: actions/download-artifact@v4
+ with:
+ name: qc-artifacts-${{ github.run_number }}
+ path: dist
+
+ - name: Sign macOS artifacts
+ if: ${{ steps.secrets_check.outputs.has_signing_cert == 'true' }}
+ env:
+ APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
+ KEYCHAIN_PATH: ${{ runner.temp }}/build.keychain-db
+ run: |
+ set -e
+ if [ -z "$APPLE_SIGNING_IDENTITY" ]; then
+ echo "::error::APPLE_SIGNING_IDENTITY is required for signing."
+ exit 1
+ fi
+ if [ ! -f dist/checksums.txt ]; then
+ echo "::error::dist/checksums.txt not found."
+ exit 1
+ fi
+
+ for archive in dist/*-darwin-*.tar.gz; do
+ [ -f "$archive" ] || continue
+ tmpdir="$(mktemp -d)"
+ orig_members=$(tar -tzf "$archive")
+ tar -xzf "$archive" -C "$tmpdir"
+
+ while IFS= read -r -d '' bin; do
+ codesign --force --options runtime --timestamp \
+ --keychain "$KEYCHAIN_PATH" \
+ --sign "$APPLE_SIGNING_IDENTITY" "$bin"
+ codesign --verify --deep --strict "$bin"
+ done < <(find "$tmpdir" -type f -perm -111 -print0)
+
+ # shellcheck disable=SC2086
+ tar -czf "${archive}.signed" -C "$tmpdir" $orig_members
+ mv "${archive}.signed" "$archive"
+ rm -rf "$tmpdir"
+
+ filename="$(basename "$archive")"
+ sha="$(shasum -a 256 "$archive" | awk '{print $1}')"
+ grep -v " $filename\$" dist/checksums.txt > dist/checksums.new || true
+ printf "%s %s\n" "$sha" "$filename" >> dist/checksums.new
+ mv dist/checksums.new dist/checksums.txt
+
+ PATCH_NAME="$filename" PATCH_SHA="$sha" python3 << 'PYEOF'
+ import json, os
+ data = json.load(open('dist/artifacts.json'))
+ name = os.environ['PATCH_NAME']
+ checksum = os.environ['PATCH_SHA']
+ for a in data:
+ if a.get('name') == name:
+ a.setdefault('extra', {})['Checksum'] = 'sha256:' + checksum
+ with open('dist/artifacts.json', 'w') as f:
+ json.dump(data, f, indent=2)
+ PYEOF
+ done
+
+ - name: Upload signed macOS artifacts
+ if: ${{ steps.secrets_check.outputs.has_signing_cert == 'true' }}
+ uses: actions/upload-artifact@v4
+ with:
+ name: qc-artifacts-macos-signed-${{ github.run_number }}
+ if-no-files-found: error
+ path: |
+ dist/*-darwin-amd64.tar.gz
+ dist/*-darwin-arm64.tar.gz
+ dist/checksums.txt
+
+ - name: Clean up keychain and cert
+ if: always()
+ run: |
+ security delete-keychain "$RUNNER_TEMP/build.keychain-db" 2>/dev/null || true
+ rm -f cert.p12
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 9d4a0d2..208409f 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -37,6 +37,22 @@ jobs:
go-version-file: go.mod
cache: true
+ - name: Verify release branch
+ run: |
+ if [[ "$GITHUB_REF" == refs/tags/* ]]; then
+ # Tag pushes don't populate origin/* remote-tracking refs, so fetch
+ # the main branches explicitly before checking containment.
+ git fetch --quiet origin '+refs/heads/main:refs/remotes/origin/main' '+refs/heads/main-*:refs/remotes/origin/main-*' || true
+ # Allow main or a main- branch (e.g. main-hotfix) for emergency releases.
+ if ! git branch -r --contains "$GITHUB_SHA" | grep -qE '^\s*origin/main($|-)'; then
+ echo "::error::Tag $GITHUB_REF_NAME must be on the main branch (or a main- branch)."
+ exit 1
+ fi
+ elif [[ "$GITHUB_REF" != "refs/heads/main" && "$GITHUB_REF" != refs/heads/main-* && "${{ inputs.snapshot }}" != "true" ]]; then
+ echo "::error::Release workflow must be dispatched from the main branch (or a main- branch, or use snapshot=true for ad-hoc builds)."
+ exit 1
+ fi
+
- name: Validate dispatch inputs
if: github.event_name == 'workflow_dispatch'
env:
@@ -76,9 +92,12 @@ jobs:
run: |
set -e
EXTRA=""
+ CONFIG=".goreleaser/config.yaml"
if [ "$SNAPSHOT" = "true" ]; then
+ # Snapshot builds are QC builds: QC endpoints, apimetrics-qc binary.
EXTRA="--snapshot --skip homebrew"
- echo "Running goreleaser in snapshot mode (no publish)"
+ CONFIG=".goreleaser/config-qc.yaml"
+ echo "Running goreleaser in snapshot mode (QC build, no publish)"
elif [[ "$GITHUB_REF" == refs/tags/* ]]; then
EXTRA="--skip publish,homebrew"
echo "Building artifacts without publishing; GitHub release and GCS upload deferred to finalization"
@@ -89,7 +108,7 @@ jobs:
-w /workspace \
-e GITHUB_TOKEN \
ghcr.io/goreleaser/goreleaser-cross:v1.25-v2.12.7 \
- release $EXTRA --clean --parallelism 2
+ release $EXTRA --config "$CONFIG" --clean --parallelism 2
- name: Create GitHub draft release
if: ${{ startsWith(github.ref, 'refs/tags/') && inputs.snapshot != true }}
@@ -127,11 +146,60 @@ jobs:
dist/artifacts.json
dist/metadata.json
+ # Snapshot (QC) builds: upload each asset as its own artifact so the
+ # Actions run lists them individually rather than as one combined zip.
+ - name: Upload QC snapshot — macOS (Intel)
+ if: ${{ inputs.snapshot == true }}
+ uses: actions/upload-artifact@v4
+ with:
+ name: apimetrics-qc-darwin-amd64
+ if-no-files-found: error
+ path: dist/*-darwin-amd64.tar.gz
+
+ - name: Upload QC snapshot — macOS (Apple Silicon)
+ if: ${{ inputs.snapshot == true }}
+ uses: actions/upload-artifact@v4
+ with:
+ name: apimetrics-qc-darwin-arm64
+ if-no-files-found: error
+ path: dist/*-darwin-arm64.tar.gz
+
+ - name: Upload QC snapshot — Linux (amd64)
+ if: ${{ inputs.snapshot == true }}
+ uses: actions/upload-artifact@v4
+ with:
+ name: apimetrics-qc-linux-amd64
+ if-no-files-found: error
+ path: dist/*-linux-amd64.tar.gz
+
+ - name: Upload QC snapshot — Linux (arm64)
+ if: ${{ inputs.snapshot == true }}
+ uses: actions/upload-artifact@v4
+ with:
+ name: apimetrics-qc-linux-arm64
+ if-no-files-found: error
+ path: dist/*-linux-arm64.tar.gz
+
+ - name: Upload QC snapshot — Windows (amd64)
+ if: ${{ inputs.snapshot == true }}
+ uses: actions/upload-artifact@v4
+ with:
+ name: apimetrics-qc-windows-amd64
+ if-no-files-found: error
+ path: dist/*-windows-amd64.zip
+
+ - name: Upload QC snapshot — checksums
+ if: ${{ inputs.snapshot == true }}
+ uses: actions/upload-artifact@v4
+ with:
+ name: checksums.txt
+ if-no-files-found: error
+ path: dist/checksums.txt
+
release-macos:
name: Sign and notarize macOS artifacts
runs-on: macos-latest
needs: release
- if: ${{ inputs.snapshot != true }}
timeout-minutes: 30
steps:
@@ -176,11 +244,21 @@ jobs:
security list-keychains -d user -s "$KEYCHAIN_PATH" $(security list-keychains -d user | tr -d '"' | xargs)
- name: Download release artifacts
+ if: ${{ inputs.snapshot != true }}
uses: actions/download-artifact@v4
with:
name: release-artifacts
path: dist
+ # Snapshot builds upload each asset as its own artifact; pull them all
+ # back (flattened) so the signing step finds the darwin archives.
+ - name: Download QC snapshot artifacts
+ if: ${{ inputs.snapshot == true }}
+ uses: actions/download-artifact@v4
+ with:
+ merge-multiple: true
+ path: dist
+
- name: Sign and notarize macOS artifacts
if: ${{ steps.secrets_check.outputs.has_signing_cert == 'true' }}
env:
@@ -237,7 +315,9 @@ jobs:
printf "%s %s\n" "$sha" "$filename" >> dist/checksums.new
mv dist/checksums.new dist/checksums.txt
- # Keep artifacts.json in sync with the signed checksums for archival accuracy.
+ # Keep artifacts.json in sync with the signed checksums for archival
+ # accuracy. Only present for full releases, not snapshot builds.
+ if [ -f dist/artifacts.json ]; then
PATCH_NAME="$filename" PATCH_SHA="$sha" python3 << 'PYEOF'
import json, os
data = json.load(open('dist/artifacts.json'))
@@ -249,10 +329,11 @@ jobs:
with open('dist/artifacts.json', 'w') as f:
json.dump(data, f, indent=2)
PYEOF
+ fi
done
- name: Upload signed macOS artifacts
- if: ${{ steps.secrets_check.outputs.has_signing_cert == 'true' }}
+ if: ${{ steps.secrets_check.outputs.has_signing_cert == 'true' && inputs.snapshot != true }}
uses: actions/upload-artifact@v4
with:
name: macos-signed-artifacts
@@ -262,6 +343,35 @@ jobs:
dist/*-darwin-arm64.tar.gz
dist/checksums.txt
+ # Snapshot builds: replace the unsigned darwin placeholders uploaded by
+ # the build job with the signed archives, listed as individual assets.
+ - name: Upload signed QC snapshot — macOS (Intel)
+ if: ${{ inputs.snapshot == true && steps.secrets_check.outputs.has_signing_cert == 'true' }}
+ uses: actions/upload-artifact@v4
+ with:
+ name: apimetrics-qc-darwin-amd64
+ overwrite: true
+ if-no-files-found: error
+ path: dist/*-darwin-amd64.tar.gz
+
+ - name: Upload signed QC snapshot — macOS (Apple Silicon)
+ if: ${{ inputs.snapshot == true && steps.secrets_check.outputs.has_signing_cert == 'true' }}
+ uses: actions/upload-artifact@v4
+ with:
+ name: apimetrics-qc-darwin-arm64
+ overwrite: true
+ if-no-files-found: error
+ path: dist/*-darwin-arm64.tar.gz
+
+ - name: Upload signed QC snapshot — checksums
+ if: ${{ inputs.snapshot == true && steps.secrets_check.outputs.has_signing_cert == 'true' }}
+ uses: actions/upload-artifact@v4
+ with:
+ name: checksums.txt
+ overwrite: true
+ if-no-files-found: error
+ path: dist/checksums.txt
+
- name: Authenticate to Google Cloud
if: ${{ startsWith(github.ref, 'refs/tags/') }}
uses: google-github-actions/auth@v2
diff --git a/.goreleaser.yml b/.goreleaser.yml
deleted file mode 100644
index 21b5759..0000000
--- a/.goreleaser.yml
+++ /dev/null
@@ -1,80 +0,0 @@
-version: 2
-
-project_name: apimetrics
-
-before:
- hooks:
- - go mod download
- # TODO: Figure out how to test with CGO on all platforms.
- - go test -v ./...
-
-builds:
- - id: apimetrics-darwin-amd64
- goos:
- - darwin
- goarch:
- - amd64
- env:
- - CGO_ENABLED=1
- - CC=o64-clang
- - CXX=o64-clang++
-
- - id: apimetrics-darwin-arm64
- goos:
- - darwin
- goarch:
- - arm64
- env:
- - CGO_ENABLED=1
- - CC=oa64-clang
- - CXX=oa64-clang++
-
- - id: apimetrics-linux-amd64
- goos:
- - linux
- goarch:
- - amd64
- env:
- - CGO_ENABLED=1
- - CC=x86_64-linux-gnu-gcc
- - CXX=x86_64-linux-gnu-g++
-
- - id: apimetrics-linux-arm64
- goos:
- - linux
- goarch:
- - arm64
- env:
- - CGO_ENABLED=1
- - CC=aarch64-linux-gnu-gcc
- - CXX=aarch64-linux-gnu-g++
-
- - id: apimetrics-windows-amd64
- goos:
- - windows
- goarch:
- - amd64
- env:
- - CGO_ENABLED=1
- - CC=x86_64-w64-mingw32-gcc
- - CXX=x86_64-w64-mingw32-g++
-
-archives:
- - name_template: "{{ .ProjectName }}-{{ .Version }}-{{ .Os }}-{{ .Arch }}"
- format_overrides:
- - goos: windows
- formats:
- - zip
-
-checksum:
- name_template: "checksums.txt"
-
-snapshot:
- version_template: "{{ .Tag }}-next"
-
-changelog:
- sort: asc
- filters:
- exclude:
- - "^docs:"
- - "^test:"
diff --git a/.goreleaser/config-qc.yaml b/.goreleaser/config-qc.yaml
new file mode 100644
index 0000000..85a699f
--- /dev/null
+++ b/.goreleaser/config-qc.yaml
@@ -0,0 +1,128 @@
+version: 2
+project_name: apimetrics-qc
+builds:
+ - id: apimetrics-qc-darwin-amd64
+ goos:
+ - darwin
+ goarch:
+ - amd64
+ targets:
+ - darwin_amd64_v1
+ dir: .
+ main: .
+ binary: apimetrics-qc
+ builder: go
+ tool: go
+ command: build
+ ldflags:
+ - -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} -X main.builtBy=goreleaser
+ env:
+ - CGO_ENABLED=1
+ - CC=o64-clang
+ - CXX=o64-clang++
+ - id: apimetrics-qc-darwin-arm64
+ goos:
+ - darwin
+ goarch:
+ - arm64
+ targets:
+ - darwin_arm64_v8.0
+ dir: .
+ main: .
+ binary: apimetrics-qc
+ builder: go
+ tool: go
+ command: build
+ ldflags:
+ - -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} -X main.builtBy=goreleaser
+ env:
+ - CGO_ENABLED=1
+ - CC=oa64-clang
+ - CXX=oa64-clang++
+ - id: apimetrics-qc-linux-amd64
+ goos:
+ - linux
+ goarch:
+ - amd64
+ targets:
+ - linux_amd64_v1
+ dir: .
+ main: .
+ binary: apimetrics-qc
+ builder: go
+ tool: go
+ command: build
+ ldflags:
+ - -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} -X main.builtBy=goreleaser
+ env:
+ - CGO_ENABLED=1
+ - CC=x86_64-linux-gnu-gcc
+ - CXX=x86_64-linux-gnu-g++
+ - id: apimetrics-qc-linux-arm64
+ goos:
+ - linux
+ goarch:
+ - arm64
+ targets:
+ - linux_arm64_v8.0
+ dir: .
+ main: .
+ binary: apimetrics-qc
+ builder: go
+ tool: go
+ command: build
+ ldflags:
+ - -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} -X main.builtBy=goreleaser
+ env:
+ - CGO_ENABLED=1
+ - CC=aarch64-linux-gnu-gcc
+ - CXX=aarch64-linux-gnu-g++
+ - id: apimetrics-qc-windows-amd64
+ goos:
+ - windows
+ goarch:
+ - amd64
+ targets:
+ - windows_amd64_v1
+ dir: .
+ main: .
+ binary: apimetrics-qc
+ builder: go
+ tool: go
+ command: build
+ ldflags:
+ - -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} -X main.builtBy=goreleaser
+ env:
+ - CGO_ENABLED=1
+ - CC=x86_64-w64-mingw32-gcc
+ - CXX=x86_64-w64-mingw32-g++
+archives:
+ - id: default
+ builds_info:
+ mode: 493
+ name_template: '{{ .ProjectName }}-{{ .Version }}-{{ .Os }}-{{ .Arch }}'
+ formats:
+ - tar.gz
+ format_overrides:
+ - goos: windows
+ formats:
+ - zip
+ files:
+ - src: license*
+ - src: LICENSE*
+ - src: readme*
+ - src: README*
+snapshot:
+ version_template: '{{ .ShortCommit }}'
+checksum:
+ name_template: checksums.txt
+ algorithm: sha256
+dist: dist
+gomod:
+ gobinary: go
+before:
+ hooks:
+ - go mod download
+ - go test -v ./...
+git:
+ tag_sort: -version:refname
diff --git a/.goreleaser/config.yaml b/.goreleaser/config.yaml
new file mode 100644
index 0000000..55927d7
--- /dev/null
+++ b/.goreleaser/config.yaml
@@ -0,0 +1,287 @@
+version: 2
+project_name: apimetrics
+release:
+ github:
+ owner: APImetrics
+ name: APImetrics-cli
+ name_template: '{{.Tag}}'
+builds:
+ - id: apimetrics-darwin-amd64
+ goos:
+ - darwin
+ goarch:
+ - amd64
+ goamd64:
+ - v1
+ go386:
+ - sse2
+ goarm:
+ - "6"
+ goarm64:
+ - v8.0
+ gomips:
+ - hardfloat
+ goppc64:
+ - power8
+ goriscv64:
+ - rva20u64
+ targets:
+ - darwin_amd64_v1
+ dir: .
+ main: .
+ binary: apimetrics
+ builder: go
+ tool: go
+ command: build
+ flags:
+ - -tags=prod
+ ldflags:
+ - -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} -X main.builtBy=goreleaser
+ env:
+ - CGO_ENABLED=1
+ - CC=o64-clang
+ - CXX=o64-clang++
+ - id: apimetrics-darwin-arm64
+ goos:
+ - darwin
+ goarch:
+ - arm64
+ goamd64:
+ - v1
+ go386:
+ - sse2
+ goarm:
+ - "6"
+ goarm64:
+ - v8.0
+ gomips:
+ - hardfloat
+ goppc64:
+ - power8
+ goriscv64:
+ - rva20u64
+ targets:
+ - darwin_arm64_v8.0
+ dir: .
+ main: .
+ binary: apimetrics
+ builder: go
+ tool: go
+ command: build
+ flags:
+ - -tags=prod
+ ldflags:
+ - -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} -X main.builtBy=goreleaser
+ env:
+ - CGO_ENABLED=1
+ - CC=oa64-clang
+ - CXX=oa64-clang++
+ - id: apimetrics-linux-amd64
+ goos:
+ - linux
+ goarch:
+ - amd64
+ goamd64:
+ - v1
+ go386:
+ - sse2
+ goarm:
+ - "6"
+ goarm64:
+ - v8.0
+ gomips:
+ - hardfloat
+ goppc64:
+ - power8
+ goriscv64:
+ - rva20u64
+ targets:
+ - linux_amd64_v1
+ dir: .
+ main: .
+ binary: apimetrics
+ builder: go
+ tool: go
+ command: build
+ flags:
+ - -tags=prod
+ ldflags:
+ - -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} -X main.builtBy=goreleaser
+ env:
+ - CGO_ENABLED=1
+ - CC=x86_64-linux-gnu-gcc
+ - CXX=x86_64-linux-gnu-g++
+ - id: apimetrics-linux-arm64
+ goos:
+ - linux
+ goarch:
+ - arm64
+ goamd64:
+ - v1
+ go386:
+ - sse2
+ goarm:
+ - "6"
+ goarm64:
+ - v8.0
+ gomips:
+ - hardfloat
+ goppc64:
+ - power8
+ goriscv64:
+ - rva20u64
+ targets:
+ - linux_arm64_v8.0
+ dir: .
+ main: .
+ binary: apimetrics
+ builder: go
+ tool: go
+ command: build
+ flags:
+ - -tags=prod
+ ldflags:
+ - -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} -X main.builtBy=goreleaser
+ env:
+ - CGO_ENABLED=1
+ - CC=aarch64-linux-gnu-gcc
+ - CXX=aarch64-linux-gnu-g++
+ - id: apimetrics-windows-amd64
+ goos:
+ - windows
+ goarch:
+ - amd64
+ goamd64:
+ - v1
+ go386:
+ - sse2
+ goarm:
+ - "6"
+ goarm64:
+ - v8.0
+ gomips:
+ - hardfloat
+ goppc64:
+ - power8
+ goriscv64:
+ - rva20u64
+ targets:
+ - windows_amd64_v1
+ dir: .
+ main: .
+ binary: apimetrics
+ builder: go
+ tool: go
+ command: build
+ flags:
+ - -tags=prod
+ ldflags:
+ - -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} -X main.builtBy=goreleaser
+ env:
+ - CGO_ENABLED=1
+ - CC=x86_64-w64-mingw32-gcc
+ - CXX=x86_64-w64-mingw32-g++
+archives:
+ - id: default
+ builds_info:
+ mode: 493
+ name_template: '{{ .ProjectName }}-{{ .Version }}-{{ .Os }}-{{ .Arch }}'
+ formats:
+ - tar.gz
+ format_overrides:
+ - goos: windows
+ formats:
+ - zip
+ files:
+ - src: license*
+ - src: LICENSE*
+ - src: readme*
+ - src: README*
+ - src: changelog*
+ - src: CHANGELOG*
+snapshot:
+ version_template: '{{ .Tag }}-next'
+checksum:
+ name_template: checksums.txt
+ algorithm: sha256
+docker_digest:
+ name_template: digests.txt
+blobs:
+ - bucket: apimetrics-cli
+ provider: gs
+ directory: '{{ .Version }}'
+ content_disposition: attachment;filename={{.Filename}}
+changelog:
+ filters:
+ exclude:
+ - '^docs:'
+ - '^test:'
+ sort: asc
+ format: '{{ .SHA }} {{ .Message }}'
+dist: dist
+env_files:
+ github_token: ~/.config/goreleaser/github_token
+ gitlab_token: ~/.config/goreleaser/gitlab_token
+ gitea_token: ~/.config/goreleaser/gitea_token
+before:
+ hooks:
+ - go mod download
+ - go test -v ./...
+source:
+ name_template: '{{ .ProjectName }}-{{ .Version }}'
+ format: tar.gz
+gomod:
+ gobinary: go
+announce:
+ twitter:
+ message_template: '{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ .ReleaseURL }}'
+ mastodon:
+ message_template: '{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ .ReleaseURL }}'
+ server: ""
+ reddit:
+ title_template: '{{ .ProjectName }} {{ .Tag }} is out!'
+ url_template: '{{ .ReleaseURL }}'
+ slack:
+ message_template: '{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ .ReleaseURL }}'
+ username: GoReleaser
+ discord:
+ message_template: '{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ .ReleaseURL }}'
+ author: GoReleaser
+ color: "3888754"
+ icon_url: https://goreleaser.com/static/avatar.png
+ teams:
+ title_template: '{{ .ProjectName }} {{ .Tag }} is out!'
+ message_template: '{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ .ReleaseURL }}'
+ color: '#2D313E'
+ icon_url: https://goreleaser.com/static/avatar.png
+ smtp:
+ subject_template: '{{ .ProjectName }} {{ .Tag }} is out!'
+ body_template: 'You can view details from: {{ .ReleaseURL }}'
+ mattermost:
+ message_template: '{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ .ReleaseURL }}'
+ title_template: '{{ .ProjectName }} {{ .Tag }} is out!'
+ username: GoReleaser
+ linkedin:
+ message_template: '{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ .ReleaseURL }}'
+ telegram:
+ message_template: '{{ mdv2escape .ProjectName }} {{ mdv2escape .Tag }} is out{{ mdv2escape "!" }} Check it out at {{ mdv2escape .ReleaseURL }}'
+ parse_mode: MarkdownV2
+ webhook:
+ message_template: '{ "message": "{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ .ReleaseURL }}"}'
+ content_type: application/json; charset=utf-8
+ expected_status_codes:
+ - 200
+ - 201
+ - 202
+ - 204
+ opencollective:
+ title_template: '{{ .Tag }}'
+ message_template: '{{ .ProjectName }} {{ .Tag }} is out!
Check it out at {{ .ReleaseURL }}'
+ bluesky:
+ message_template: '{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ .ReleaseURL }}'
+git:
+ tag_sort: -version:refname
+github_urls:
+ download: https://github.com
+gitlab_urls:
+ download: https://gitlab.com
diff --git a/bench_test.go b/bench_test.go
index a4ed1a0..2bf729a 100644
--- a/bench_test.go
+++ b/bench_test.go
@@ -6,10 +6,10 @@ import (
"net/http"
"testing"
- "github.com/amzn/ion-go/ion"
- "github.com/fxamacker/cbor/v2"
"apicontext.com/apimetrics/cli"
"apicontext.com/apimetrics/openapi"
+ "github.com/amzn/ion-go/ion"
+ "github.com/fxamacker/cbor/v2"
"github.com/shamaton/msgpack/v2"
"github.com/spf13/cobra"
)
diff --git a/config_dev.go b/config_dev.go
new file mode 100644
index 0000000..a6f856d
--- /dev/null
+++ b/config_dev.go
@@ -0,0 +1,9 @@
+//go:build dev && !prod
+
+package main
+
+var baseURL = "http://localhost:8080"
+var authURL = "https://local-apimetrics.auth0.com/authorize"
+var tokenURL = "https://local-apimetrics.auth0.com/oauth/token"
+var authAudience = "https://apimetrics-qc.appspot.com"
+var clientID = "bpplXMDCn187JipRLl6Y9KrsTVZCJTbS"
diff --git a/config_prod.go b/config_prod.go
new file mode 100644
index 0000000..ef370a8
--- /dev/null
+++ b/config_prod.go
@@ -0,0 +1,9 @@
+//go:build prod
+
+package main
+
+var baseURL = "https://client.apimetrics.io"
+var authURL = "https://auth.apimetrics.io/authorize"
+var tokenURL = "https://auth.apimetrics.io/oauth/token"
+var authAudience = "https://client.apimetrics.io"
+var clientID = "dPbV4VPvioF4nZ3oGQMn7n1vE2pFNAAI"
diff --git a/config_qc.go b/config_qc.go
new file mode 100644
index 0000000..2691890
--- /dev/null
+++ b/config_qc.go
@@ -0,0 +1,9 @@
+//go:build !prod && !dev
+
+package main
+
+var baseURL = "https://qc-client.apimetrics.io"
+var authURL = "https://qc-auth.apimetrics.io/authorize"
+var tokenURL = "https://qc-auth.apimetrics.io/oauth/token"
+var authAudience = "https://client.apimetrics.io"
+var clientID = "4fhqu4lEH5ExaRh00X1B9WJSkjTnUmuK"
diff --git a/main.go b/main.go
index db8bc01..caed2aa 100644
--- a/main.go
+++ b/main.go
@@ -11,17 +11,9 @@ import (
)
var version string = "dev"
-var commit string
-var date string
-
-// Build-time API configuration — override with -ldflags at build time:
-//
-// go build -ldflags "-X main.baseURL=https://client.apimetrics.io ..."
-var baseURL = "https://qc-client.apimetrics.io"
-var authURL = "https://qc-auth.apimetrics.io/authorize"
-var tokenURL = "https://qc-auth.apimetrics.io/oauth/token"
-var authAudience = "https://client.apimetrics.io"
-var clientID = "bj0yh0AjBMzfeOpffmCj5UP8FbmYDwcM"
+
+// baseURL, authURL, tokenURL, authAudience, clientID are defined in
+// config_qc.go (default) or config_prod.go (build tag: prod).
func main() {
if version == "dev" {
diff --git a/oauth/authcode.go b/oauth/authcode.go
index bde8881..5ff2eef 100644
--- a/oauth/authcode.go
+++ b/oauth/authcode.go
@@ -6,6 +6,7 @@ import (
"crypto/sha256"
"encoding/base64"
"fmt"
+ "html"
"net/http"
"net/url"
"os"
@@ -22,105 +23,151 @@ import (
)
var htmlSuccess = `
-
+
+
+
+ Please return to the terminal. You may now close this window.
+ $ERROR
$DETAILS