fix(ci): mitigate GitHub API rate-limit failures (#334)

* fix(ci): mitigate GitHub API rate-limit failures in workflows

* fix(ci): resolve signature drift blocking Docker smoke
This commit is contained in:
Will Sarg 2026-02-16 08:05:52 -05:00 committed by GitHub
parent 07dc8b3927
commit b76a3879a9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 661 additions and 635 deletions

View file

@ -81,17 +81,26 @@ jobs:
username: ${{ github.actor }} username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) - name: Compute tags
id: meta id: meta
uses: docker/metadata-action@v5 shell: bash
with: run: |
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} set -euo pipefail
tags: | IMAGE="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}"
type=ref,event=branch SHA_TAG="${IMAGE}:sha-${GITHUB_SHA::12}"
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}} if [[ "${GITHUB_REF}" == refs/tags/* ]]; then
type=semver,pattern={{major}} TAG_NAME="${GITHUB_REF#refs/tags/}"
type=raw,value=latest,enable={{is_default_branch}} TAGS="${IMAGE}:${TAG_NAME},${SHA_TAG}"
elif [[ "${GITHUB_REF}" == "refs/heads/main" ]]; then
TAGS="${IMAGE}:latest,${SHA_TAG}"
else
BRANCH_NAME="${GITHUB_REF#refs/heads/}"
BRANCH_NAME="${BRANCH_NAME//\//-}"
TAGS="${IMAGE}:${BRANCH_NAME},${SHA_TAG}"
fi
echo "tags=${TAGS}" >> "$GITHUB_OUTPUT"
- name: Build and push Docker image - name: Build and push Docker image
uses: docker/build-push-action@v5 uses: docker/build-push-action@v5
@ -99,7 +108,6 @@ jobs:
context: . context: .
push: true push: true
tags: ${{ steps.meta.outputs.tags }} tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha cache-from: type=gha
cache-to: type=gha,mode=max cache-to: type=gha,mode=max
platforms: ${{ startsWith(github.ref, 'refs/tags/') && 'linux/amd64,linux/arm64' || 'linux/amd64' }} platforms: ${{ startsWith(github.ref, 'refs/tags/') && 'linux/amd64,linux/arm64' || 'linux/amd64' }}

File diff suppressed because it is too large Load diff

View file

@ -50,6 +50,7 @@ const CHANNEL_MAX_IN_FLIGHT_MESSAGES: usize = 64;
struct ChannelRuntimeContext { struct ChannelRuntimeContext {
channels_by_name: Arc<HashMap<String, Arc<dyn Channel>>>, channels_by_name: Arc<HashMap<String, Arc<dyn Channel>>>,
provider: Arc<dyn Provider>, provider: Arc<dyn Provider>,
provider_name: Arc<String>,
memory: Arc<dyn Memory>, memory: Arc<dyn Memory>,
tools_registry: Arc<Vec<Box<dyn Tool>>>, tools_registry: Arc<Vec<Box<dyn Tool>>>,
observer: Arc<dyn Observer>, observer: Arc<dyn Observer>,
@ -185,6 +186,7 @@ async fn process_channel_message(ctx: Arc<ChannelRuntimeContext>, msg: traits::C
&mut history, &mut history,
ctx.tools_registry.as_ref(), ctx.tools_registry.as_ref(),
ctx.observer.as_ref(), ctx.observer.as_ref(),
ctx.provider_name.as_str(),
ctx.model.as_str(), ctx.model.as_str(),
ctx.temperature, ctx.temperature,
), ),
@ -677,8 +679,12 @@ pub async fn doctor_channels(config: Config) -> Result<()> {
/// Start all configured channels and route messages to the agent /// Start all configured channels and route messages to the agent
#[allow(clippy::too_many_lines)] #[allow(clippy::too_many_lines)]
pub async fn start_channels(config: Config) -> Result<()> { pub async fn start_channels(config: Config) -> Result<()> {
let provider_name = config
.default_provider
.clone()
.unwrap_or_else(|| "openrouter".to_string());
let provider: Arc<dyn Provider> = Arc::from(providers::create_resilient_provider( let provider: Arc<dyn Provider> = Arc::from(providers::create_resilient_provider(
config.default_provider.as_deref().unwrap_or("openrouter"), provider_name.as_str(),
config.api_key.as_deref(), config.api_key.as_deref(),
&config.reliability, &config.reliability,
)?); )?);
@ -721,6 +727,7 @@ pub async fn start_channels(config: Config) -> Result<()> {
composio_key, composio_key,
&config.browser, &config.browser,
&config.http_request, &config.http_request,
&config.workspace_dir,
&config.agents, &config.agents,
config.api_key.as_deref(), config.api_key.as_deref(),
)); ));
@ -927,6 +934,7 @@ pub async fn start_channels(config: Config) -> Result<()> {
let runtime_ctx = Arc::new(ChannelRuntimeContext { let runtime_ctx = Arc::new(ChannelRuntimeContext {
channels_by_name, channels_by_name,
provider: Arc::clone(&provider), provider: Arc::clone(&provider),
provider_name: Arc::new(provider_name),
memory: Arc::clone(&mem), memory: Arc::clone(&mem),
tools_registry: Arc::clone(&tools_registry), tools_registry: Arc::clone(&tools_registry),
observer, observer,
@ -1121,6 +1129,7 @@ mod tests {
let runtime_ctx = Arc::new(ChannelRuntimeContext { let runtime_ctx = Arc::new(ChannelRuntimeContext {
channels_by_name: Arc::new(channels_by_name), channels_by_name: Arc::new(channels_by_name),
provider: Arc::new(ToolCallingProvider), provider: Arc::new(ToolCallingProvider),
provider_name: Arc::new("test-provider".to_string()),
memory: Arc::new(NoopMemory), memory: Arc::new(NoopMemory),
tools_registry: Arc::new(vec![Box::new(MockPriceTool)]), tools_registry: Arc::new(vec![Box::new(MockPriceTool)]),
observer: Arc::new(NoopObserver), observer: Arc::new(NoopObserver),
@ -1211,6 +1220,7 @@ mod tests {
provider: Arc::new(SlowProvider { provider: Arc::new(SlowProvider {
delay: Duration::from_millis(250), delay: Duration::from_millis(250),
}), }),
provider_name: Arc::new("test-provider".to_string()),
memory: Arc::new(NoopMemory), memory: Arc::new(NoopMemory),
tools_registry: Arc::new(vec![]), tools_registry: Arc::new(vec![]),
observer: Arc::new(NoopObserver), observer: Arc::new(NoopObserver),

View file

@ -193,7 +193,8 @@ async fn run_heartbeat_worker(config: Config) -> Result<()> {
for task in tasks { for task in tasks {
let prompt = format!("[Heartbeat Task] {task}"); let prompt = format!("[Heartbeat Task] {task}");
let temp = config.default_temperature; let temp = config.default_temperature;
if let Err(e) = crate::agent::run(config.clone(), Some(prompt), None, None, temp).await if let Err(e) =
crate::agent::run(config.clone(), Some(prompt), None, None, temp, false).await
{ {
crate::health::mark_component_error("heartbeat", e.to_string()); crate::health::mark_component_error("heartbeat", e.to_string());
tracing::warn!("Heartbeat task failed: {e}"); tracing::warn!("Heartbeat task failed: {e}");