Skip to content

Fix agent task long-poll timeout defaults #64

Fix agent task long-poll timeout defaults

Fix agent task long-poll timeout defaults #64

Workflow file for this run

name: Publish Agent Release
on:
push:
branches:
- main
tags:
- agent-v*
paths:
- .github/workflows/agent-release.yml
- CHANGELOG.md
- cmd/**
- internal/**
- scripts/**
- go.mod
- go.sum
- README.md
- config.example.json
workflow_dispatch:
inputs:
release_version:
description: Optional existing tagged release version such as 0.1.0
required: false
type: string
publish_latest:
description: Also refresh the latest channel
required: true
default: true
type: boolean
concurrency:
group: agent-release-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: write
jobs:
publish:
name: Build and publish agent artifacts
runs-on: ubuntu-latest
env:
AWS_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
AWS_REGION: auto
R2_ACCOUNT_ID: ${{ secrets.R2_ACCOUNT_ID }}
R2_BUCKET: ${{ secrets.R2_BUCKET }}
PUBLIC_RELEASE_BASE_URL: https://cdn.noderax.net/noderax-agent/releases
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: "1.22"
- name: Verify dependencies
run: go mod verify
- name: Test
run: go test ./...
- name: Install release signing tools
shell: bash
run: |
set -euo pipefail
sudo apt-get update
sudo apt-get install -y minisign
- name: Prepare minisign secret key
id: minisign
shell: bash
env:
AGENT_MINISIGN_SECRET_KEY_B64: ${{ secrets.AGENT_MINISIGN_SECRET_KEY_B64 }}
run: |
set -euo pipefail
: "${AGENT_MINISIGN_SECRET_KEY_B64:?Missing AGENT_MINISIGN_SECRET_KEY_B64 secret}"
key_path="${RUNNER_TEMP}/noderax-agent-minisign.key"
umask 077
printf '%s' "${AGENT_MINISIGN_SECRET_KEY_B64}" | base64 -d > "${key_path}"
echo "key_path=${key_path}" >> "${GITHUB_OUTPUT}"
- name: Resolve release metadata
id: release
shell: bash
run: |
set -euo pipefail
trim() {
local value="${1:-}"
value="${value#"${value%%[![:space:]]*}"}"
value="${value%"${value##*[![:space:]]}"}"
printf '%s' "${value}"
}
release_version=""
publish_latest="true"
if [[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" ]]; then
release_version="$(trim "${{ inputs.release_version }}")"
publish_latest="${{ inputs.publish_latest }}"
elif [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
release_version="$(trim "${GITHUB_REF_NAME#agent-v}")"
fi
if [[ -n "${release_version}" && ! "${release_version}" =~ ^[A-Za-z0-9._-]+$ ]]; then
echo "Release version must be URL-safe. Got: ${release_version}" >&2
exit 1
fi
if [[ -n "${release_version}" ]]; then
if ! git rev-parse --verify "refs/tags/agent-v${release_version}" >/dev/null 2>&1; then
echo "Versioned releases must map to an existing git tag agent-v${release_version}." >&2
exit 1
fi
fi
binary_version="${release_version}"
if [[ -z "${binary_version}" ]]; then
binary_version="main-${GITHUB_SHA::7}"
fi
build_date="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
echo "release_version=${release_version}" >> "${GITHUB_OUTPUT}"
echo "binary_version=${binary_version}" >> "${GITHUB_OUTPUT}"
echo "publish_latest=${publish_latest}" >> "${GITHUB_OUTPUT}"
echo "build_date=${build_date}" >> "${GITHUB_OUTPUT}"
- name: Build release assets
shell: bash
run: |
set -euo pipefail
chmod +x ./scripts/build-release.sh
build_args=(
--version "${{ steps.release.outputs.binary_version }}"
--commit "${GITHUB_SHA}"
--build-date "${{ steps.release.outputs.build_date }}"
--output-dir "./dist/release"
--release-base-url "${PUBLIC_RELEASE_BASE_URL}"
--minisign-secret-key-file "${{ steps.minisign.outputs.key_path }}"
)
if [[ "${{ steps.release.outputs.release_version }}" == "" ]]; then
build_args+=(--release-artifact-channel "latest")
fi
./scripts/build-release.sh "${build_args[@]}"
- name: Generate tagged release metadata
if: steps.release.outputs.release_version != ''
shell: bash
run: |
set -euo pipefail
version="${{ steps.release.outputs.release_version }}"
download_base_url="${PUBLIC_RELEASE_BASE_URL}/${version}"
go run ./cmd/release-metadata bundle \
--version "${version}" \
--commit "${GITHUB_SHA}" \
--published-at "${{ steps.release.outputs.build_date }}" \
--artifacts-dir "./dist/release" \
--download-base-url "${download_base_url}" \
--manifest-output "./dist/release/release-manifest.json" \
--release-notes-output "./dist/release/release-notes.md" \
--changelog "./CHANGELOG.md"
if curl -fsSL "${PUBLIC_RELEASE_BASE_URL}/catalog.json" -o "./dist/release/catalog-existing.json"; then
echo "Loaded existing CDN catalog."
else
printf '{\"releases\":[]}\n' > "./dist/release/catalog-existing.json"
fi
go run ./cmd/release-metadata catalog \
--manifest "./dist/release/release-manifest.json" \
--existing "./dist/release/catalog-existing.json" \
--output "./dist/release/catalog.json"
- name: Sign release manifest
shell: bash
run: |
set -euo pipefail
minisign -Sm "./dist/release/release-manifest.json" \
-s "${{ steps.minisign.outputs.key_path }}" \
-x "./dist/release/release-manifest.json.minisig"
- name: Show release assets
run: ls -lah ./dist/release
- name: Validate R2 configuration
id: r2
shell: bash
run: |
set -euo pipefail
trim() {
local value="${1:-}"
value="${value#"${value%%[![:space:]]*}"}"
value="${value%"${value##*[![:space:]]}"}"
printf '%s' "${value}"
}
: "${AWS_ACCESS_KEY_ID:?Missing R2_ACCESS_KEY_ID secret}"
: "${AWS_SECRET_ACCESS_KEY:?Missing R2_SECRET_ACCESS_KEY secret}"
: "${R2_ACCOUNT_ID:?Missing R2_ACCOUNT_ID secret}"
: "${R2_BUCKET:?Missing R2_BUCKET secret}"
raw_bucket="$(trim "${R2_BUCKET}")"
if [[ "${raw_bucket}" == s3://* ]]; then
raw_bucket="${raw_bucket#s3://}"
fi
if [[ "${raw_bucket}" == http://* || "${raw_bucket}" == https://* ]]; then
path_part="${raw_bucket#http://}"
path_part="${path_part#https://}"
if [[ "${path_part}" != */* ]]; then
echo "R2_BUCKET must be the bucket name only, not a URL without a bucket path." >&2
echo "Example: media-assets" >&2
exit 1
fi
raw_bucket="${path_part#*/}"
fi
raw_bucket="${raw_bucket#/}"
raw_bucket="${raw_bucket%%/*}"
if [[ -z "${raw_bucket}" ]]; then
echo "Resolved R2 bucket name is empty. Set R2_BUCKET to your bucket name, for example media-assets." >&2
exit 1
fi
if [[ ! "${raw_bucket}" =~ ^[a-zA-Z0-9._-]{1,255}$ ]]; then
echo "Resolved R2 bucket name is invalid: ${raw_bucket}" >&2
echo "Set R2_BUCKET to the plain bucket name only, without https:// or extra path segments." >&2
exit 1
fi
echo "bucket_name=${raw_bucket}" >> "${GITHUB_OUTPUT}"
echo "endpoint_url=https://${R2_ACCOUNT_ID}.r2.cloudflarestorage.com" >> "${GITHUB_OUTPUT}"
aws --version
- name: Verify R2 bucket exists
shell: bash
run: |
set -euo pipefail
endpoint="${{ steps.r2.outputs.endpoint_url }}"
bucket="${{ steps.r2.outputs.bucket_name }}"
if ! aws s3api head-bucket --bucket "${bucket}" --endpoint-url "${endpoint}" >/dev/null 2>&1; then
echo "R2 bucket '${bucket}' was not found for the configured account/credentials." >&2
echo "Check that R2_BUCKET matches the exact bucket name in Cloudflare R2." >&2
echo "Also confirm R2_ACCOUNT_ID and the access keys belong to the same Cloudflare account as that bucket." >&2
exit 1
fi
- name: Publish installer and latest channel
if: steps.release.outputs.publish_latest == 'true'
shell: bash
run: |
set -euo pipefail
endpoint="${{ steps.r2.outputs.endpoint_url }}"
bucket="s3://${{ steps.r2.outputs.bucket_name }}"
aws s3 cp ./dist/release/install.sh "${bucket}/noderax-agent/install.sh" \
--endpoint-url "${endpoint}" \
--cache-control "public, max-age=300" \
--content-type "text/x-shellscript; charset=utf-8"
aws s3 cp ./dist/release/noderax-agent-linux-amd64 "${bucket}/noderax-agent/releases/latest/noderax-agent-linux-amd64" \
--endpoint-url "${endpoint}" \
--cache-control "public, max-age=300" \
--content-type "application/octet-stream"
aws s3 cp ./dist/release/noderax-agent-linux-arm64 "${bucket}/noderax-agent/releases/latest/noderax-agent-linux-arm64" \
--endpoint-url "${endpoint}" \
--cache-control "public, max-age=300" \
--content-type "application/octet-stream"
aws s3 cp ./dist/release/SHA256SUMS "${bucket}/noderax-agent/releases/latest/SHA256SUMS" \
--endpoint-url "${endpoint}" \
--cache-control "public, max-age=300" \
--content-type "text/plain; charset=utf-8"
aws s3 cp ./dist/release/release-manifest.json "${bucket}/noderax-agent/releases/latest/release-manifest.json" \
--endpoint-url "${endpoint}" \
--cache-control "public, max-age=300" \
--content-type "application/json; charset=utf-8"
aws s3 cp ./dist/release/release-manifest.json.minisig "${bucket}/noderax-agent/releases/latest/release-manifest.json.minisig" \
--endpoint-url "${endpoint}" \
--cache-control "public, max-age=300" \
--content-type "application/octet-stream"
- name: Publish versioned release and catalog
if: steps.release.outputs.release_version != ''
shell: bash
run: |
set -euo pipefail
endpoint="${{ steps.r2.outputs.endpoint_url }}"
bucket="s3://${{ steps.r2.outputs.bucket_name }}"
version="${{ steps.release.outputs.release_version }}"
aws s3 cp ./dist/release/noderax-agent-linux-amd64 "${bucket}/noderax-agent/releases/${version}/noderax-agent-linux-amd64" \
--endpoint-url "${endpoint}" \
--cache-control "public, max-age=31536000, immutable" \
--content-type "application/octet-stream"
aws s3 cp ./dist/release/noderax-agent-linux-arm64 "${bucket}/noderax-agent/releases/${version}/noderax-agent-linux-arm64" \
--endpoint-url "${endpoint}" \
--cache-control "public, max-age=31536000, immutable" \
--content-type "application/octet-stream"
aws s3 cp ./dist/release/SHA256SUMS "${bucket}/noderax-agent/releases/${version}/SHA256SUMS" \
--endpoint-url "${endpoint}" \
--cache-control "public, max-age=31536000, immutable" \
--content-type "text/plain; charset=utf-8"
aws s3 cp ./dist/release/install.sh "${bucket}/noderax-agent/releases/${version}/install.sh" \
--endpoint-url "${endpoint}" \
--cache-control "public, max-age=31536000, immutable" \
--content-type "text/x-shellscript; charset=utf-8"
aws s3 cp ./dist/release/release-manifest.json "${bucket}/noderax-agent/releases/${version}/release-manifest.json" \
--endpoint-url "${endpoint}" \
--cache-control "public, max-age=31536000, immutable" \
--content-type "application/json; charset=utf-8"
aws s3 cp ./dist/release/release-manifest.json.minisig "${bucket}/noderax-agent/releases/${version}/release-manifest.json.minisig" \
--endpoint-url "${endpoint}" \
--cache-control "public, max-age=31536000, immutable" \
--content-type "application/octet-stream"
aws s3 cp ./dist/release/catalog.json "${bucket}/noderax-agent/releases/catalog.json" \
--endpoint-url "${endpoint}" \
--cache-control "public, max-age=300" \
--content-type "application/json; charset=utf-8"
- name: Publish GitHub Release metadata
if: steps.release.outputs.release_version != ''
uses: softprops/action-gh-release@v2
with:
tag_name: agent-v${{ steps.release.outputs.release_version }}
name: Noderax Agent ${{ steps.release.outputs.release_version }}
body_path: ./dist/release/release-notes.md
fail_on_unmatched_files: true
files: |
./dist/release/noderax-agent-linux-amd64
./dist/release/noderax-agent-linux-arm64
./dist/release/SHA256SUMS
./dist/release/install.sh
./dist/release/release-manifest.json
./dist/release/release-manifest.json.minisig