mirror of
https://github.com/luxfi/explorer.git
synced 2026-09-24 00:25:12 +00:00
luxfi/indexer v1.5.6 asked eth_getTransactionReceipt once per transaction and
dropped the transaction on any error — `if err != nil || tx == nil { continue }`,
twice over, with nothing logged. Measured on lux mainnet 96369: block 2 carries
571 transactions, the node serves all 571 and all 571 receipts, and the store
holds 562. The nine that vanished are transactionIndex 407..415, one contiguous
run in the middle of 571 back-to-back calls against one node.
v1.5.8 reads eth_getBlockByNumber(full) plus eth_getBlockReceipts — two round
trips per block where this cost two per transaction — so a receipt read that
fails takes the execution result with it and leaves the transaction, and a
transaction can no longer disappear because the node was busy.
The release job also asked for a runner label nothing carries. Every runner this
forge spawns registers `linux-amd64`; `lux-build-linux-amd64` has never existed,
and a job naming a label no runner has does not fail, it waits — which is why
1.5.49 is the newest image.
Co-authored-by: Hanzo Dev <[email protected]>
104 lines
4.2 KiB
YAML
104 lines
4.2 KiB
YAML
name: Release
|
|
|
|
# Builds ghcr.io/luxfi/explorer on the native runners (git.hanzo.ai → git-runner).
|
|
#
|
|
# This replaces .github/workflows/docker.yml, which ran on `runs-on: lux-build` —
|
|
# an ARC autoscaling runner set that no longer exists. Neither cluster has the ARC
|
|
# CRDs, and github.com/luxfi reports zero runners at org and repo scope, so every
|
|
# v* tag queued a job nothing could pick up. A job naming a label no runner carries
|
|
# does not fail; it waits. That is why v1.5.4 was tagged and never became an image.
|
|
#
|
|
# `linux-amd64` is that label read off the pool rather than chosen: every runner
|
|
# this forge spawns registers `RUNNER_LABELS=linux-amd64:host`, and hanzo/universe
|
|
# — which does build — asks for exactly that. `lux-build-linux-amd64` was the
|
|
# second name for the same idea and no runner has ever carried it, so this file
|
|
# had inherited the waiting-forever it was written to end.
|
|
#
|
|
# Same shape as luxfi/graph's release.yml: ghcr auth via the org GHCR_USER /
|
|
# GHCR_TOKEN secrets sourced from KMS (the instance GITHUB_TOKEN on this forge is a
|
|
# Hanzo Git token and carries no rights at ghcr.io), and a registry layer cache
|
|
# rather than type=gha, which is a GitHub-hosted service.
|
|
#
|
|
# Semver-only: only a v* tag produces a {{version}} manifest, plus an immutable sha
|
|
# tag on every run. No :latest, no floating tags.
|
|
|
|
on:
|
|
push:
|
|
tags: ['v*']
|
|
workflow_dispatch:
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
# A release is not made irrelevant by a newer one — let it finish.
|
|
concurrency:
|
|
group: release-${{ github.ref }}
|
|
cancel-in-progress: false
|
|
|
|
jobs:
|
|
docker:
|
|
runs-on: [linux-amd64]
|
|
timeout-minutes: 45
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- uses: docker/setup-buildx-action@v3
|
|
with:
|
|
driver: docker-container
|
|
driver-opts: network=host
|
|
|
|
# ghcr.io intermittently rejects a good credential: `Get
|
|
# "https://ghcr.io/v2/": denied: denied`. Measured on this forge over 24h,
|
|
# luxfi logins were 20 failures in ~150, spread across a dozen runners and
|
|
# arriving in bursts, with the SAME org secret succeeding either side —
|
|
# including two hours after a burst. So it is neither an expired token nor
|
|
# a sick runner, and re-reading it as either sends you to rotate a
|
|
# credential that is fine.
|
|
#
|
|
# docker/login-action does not retry, and the job dies at step 2 of 5, so
|
|
# every occurrence silently costs a release: v1.5.8 was tagged, built
|
|
# nothing, and left 1.5.7 as the newest image with no failed push to show
|
|
# for it. Retry here rather than re-running by hand.
|
|
#
|
|
# --password-stdin, so the token is never an argument and never lands in
|
|
# a process list or a log.
|
|
- name: Log in to ghcr.io
|
|
env:
|
|
GHCR_USER: ${{ secrets.GHCR_USER }}
|
|
GHCR_TOKEN: ${{ secrets.GHCR_TOKEN }}
|
|
run: |
|
|
for i in 1 2 3 4 5; do
|
|
if printf %s "$GHCR_TOKEN" | docker login ghcr.io -u "$GHCR_USER" --password-stdin; then
|
|
exit 0
|
|
fi
|
|
echo "ghcr.io login attempt $i failed; retrying in $((i * 5))s"
|
|
sleep $((i * 5))
|
|
done
|
|
echo "::error::ghcr.io refused the credential on 5 attempts over 75s — this is no longer the intermittent failure this retry covers"
|
|
exit 1
|
|
|
|
- id: meta
|
|
uses: docker/metadata-action@v5
|
|
with:
|
|
images: ghcr.io/luxfi/explorer
|
|
flavor: latest=false
|
|
labels: |
|
|
org.opencontainers.image.source=https://github.com/luxfi/explorer
|
|
tags: |
|
|
type=semver,pattern={{version}}
|
|
type=sha,prefix=sha-
|
|
|
|
# amd64 only. The pool is amd64, and this build (cgo + sqlite) under QEMU
|
|
# arm64 emulation goes from minutes to hours; arm64 returns when we own an
|
|
# arm64 runner, as a native matrix entry.
|
|
- uses: docker/build-push-action@v6
|
|
with:
|
|
context: .
|
|
platforms: linux/amd64
|
|
labels: ${{ steps.meta.outputs.labels }}
|
|
tags: ${{ steps.meta.outputs.tags }}
|
|
cache-from: type=registry,ref=ghcr.io/luxfi/explorer:buildcache-amd64
|
|
cache-to: type=registry,ref=ghcr.io/luxfi/explorer:buildcache-amd64,mode=max
|
|
provenance: false
|
|
push: true
|