PHPackages                             conduit-ui/action - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. conduit-ui/action

AbandonedArchivedLibrary

conduit-ui/action
=================

GitHub Actions operations for the Conduit agent ecosystem

00PHP

Since Dec 11Pushed 5mo agoCompare

[ Source](https://github.com/conduit-ui/action)[ Packagist](https://packagist.org/packages/conduit-ui/action)[ RSS](/packages/conduit-ui-action/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependenciesVersions (1)Used By (0)

Action
======

[](#action)

[![Latest Version on Packagist](https://camo.githubusercontent.com/93df8fff3ca20436a87b9e11722a7f0908ec0489ef952a844c02782052ae0453/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f636f6e647569742d75692f616374696f6e2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/conduit-ui/action)[![Total Downloads](https://camo.githubusercontent.com/d85ecd820db752c4b5a1bcbff90aa7f8f03c2dc462512e867297bcc6623bfc64/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f636f6e647569742d75692f616374696f6e2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/conduit-ui/action)[![Tests](https://camo.githubusercontent.com/c14c9f902c30697e9d77ef83c2d108ab4e8f530be68d2eb9b43565dcdc698edd/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f636f6e647569742d75692f616374696f6e2f74657374732e796d6c3f6272616e63683d6d6173746572266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/conduit-ui/action/actions)

**Your GitHub Actions bill is too high.** Delete stale artifacts, monitor failing workflows, and automate runner management from PHP.

Built for teams tired of manually cleaning up artifacts and babysitting CI/CD pipelines.

The Problem
-----------

[](#the-problem)

You're burning money on:

- Artifacts nobody downloaded (storage costs add up fast)
- Failed workflow runs you forgot to rerun
- Workflows running on the wrong branch
- Manual artifact downloads for debugging
- Workflow runs you can't easily track

GitHub charges $0.25/GB for artifact storage. A single forgotten artifact can cost hundreds per month.

Installation
------------

[](#installation)

```
composer require conduit-ui/action
```

Usage
-----

[](#usage)

### Stop Wasting Money on Artifacts

[](#stop-wasting-money-on-artifacts)

```
use ConduitUI\Action\Facades\Actions;

// Find artifacts older than 30 days
$artifacts = Actions::listArtifactsForRepository('your-org/your-repo');

$stale = $artifacts->filter(function ($artifact) {
    return $artifact->createdAt->diffInDays(now()) > 30;
});

// Delete them (save $$$ immediately)
foreach ($stale as $artifact) {
    Actions::deleteArtifact('your-org/your-repo', $artifact->id);
    echo "Deleted {$artifact->name} ({$artifact->sizeInMb()} MB)\n";
}

// Savings: $0.25/GB × cleaned storage
```

### Auto-Retry Failed Workflows

[](#auto-retry-failed-workflows)

```
// Get failed runs from today
$runs = Actions::listWorkflowRuns('your-org/your-repo', [
    'status' => 'completed',
    'conclusion' => 'failure',
    'created' => '>=' . now()->startOfDay()->toIso8601String(),
]);

// Retry only the failed jobs
foreach ($runs as $run) {
    Actions::rerunFailedJobs('your-org/your-repo', $run->id);
    echo "Retrying failed jobs in run #{$run->runNumber}\n";
}
```

### Download Artifacts for Debugging

[](#download-artifacts-for-debugging)

```
// Get the latest build artifact
$artifacts = Actions::listArtifactsForWorkflowRun(
    'your-org/your-repo',
    $runId
);

$buildArtifact = $artifacts->firstWhere('name', 'build-output');

if ($buildArtifact && !$buildArtifact->isExpired()) {
    $zipContent = Actions::downloadArtifact(
        'your-org/your-repo',
        $buildArtifact->id
    );

    file_put_contents('/tmp/build.zip', $zipContent);
}
```

### Monitor Workflow Health

[](#monitor-workflow-health)

```
// Check if CI is healthy
$runs = Actions::listWorkflowRuns('your-org/your-repo', [
    'workflow_id' => 'ci.yml',
    'branch' => 'main',
]);

$recent = $runs->take(10);
$failureRate = $recent->filter(fn($r) => $r->wasFailed())->count() / $recent->count();

if ($failureRate > 0.3) {
    // Alert: CI is failing 30%+ of the time
    notify("CI health degraded: {$failureRate}% failure rate");
}
```

### Workflow Automation

[](#workflow-automation)

```
// Trigger a deployment
Actions::createWorkflowDispatch(
    'your-org/your-repo',
    'deploy.yml',
    'main',
    [
        'environment' => 'production',
        'version' => 'v2.4.1',
    ]
);

// Disable a problematic workflow
Actions::disableWorkflow('your-org/your-repo', 'broken.yml');

// Enable it after fixing
Actions::enableWorkflow('your-org/your-repo', 'broken.yml');
```

### Cost Analysis Dashboard

[](#cost-analysis-dashboard)

```
// Calculate artifact storage costs
$artifacts = Actions::listArtifactsForRepository('your-org/your-repo');

$stats = [
    'total_artifacts' => $artifacts->count(),
    'total_size_gb' => $artifacts->sum(fn($a) => $a->sizeInMb()) / 1024,
    'expired' => $artifacts->filter(fn($a) => $a->isExpired())->count(),
    'monthly_cost' => ($artifacts->sum(fn($a) => $a->sizeInMb()) / 1024) * 0.25,
];

// Breakdown by workflow
$byWorkflow = $artifacts->groupBy('workflowRun.name')->map(function ($items, $name) {
    return [
        'count' => $items->count(),
        'size_mb' => $items->sum(fn($a) => $a->sizeInMb()),
        'cost' => ($items->sum(fn($a) => $a->sizeInMb()) / 1024) * 0.25,
    ];
});
```

API Reference
-------------

[](#api-reference)

### Workflows

[](#workflows)

```
Actions::listWorkflows('owner', 'repo')
Actions::getWorkflow('owner', 'repo', 'ci.yml')
Actions::disableWorkflow('owner', 'repo', 'ci.yml')
Actions::enableWorkflow('owner', 'repo', 'ci.yml')
Actions::createWorkflowDispatch('owner', 'repo', 'deploy.yml', 'main', ['key' => 'value'])
```

### Workflow Runs

[](#workflow-runs)

```
Actions::listWorkflowRuns('owner', 'repo', [
    'status' => 'completed',        // queued, in_progress, completed
    'conclusion' => 'success',      // success, failure, cancelled
    'branch' => 'main',
    'event' => 'push',              // push, pull_request, workflow_dispatch
])
Actions::getWorkflowRun('owner', 'repo', $runId)
Actions::cancelWorkflowRun('owner', 'repo', $runId)
Actions::rerunWorkflowRun('owner', 'repo', $runId)
Actions::rerunFailedJobs('owner', 'repo', $runId)
Actions::deleteWorkflowRun('owner', 'repo', $runId)
```

### Jobs

[](#jobs)

```
Actions::listJobsForWorkflowRun('owner', 'repo', $runId)
Actions::getJob('owner', 'repo', $jobId)
Actions::getJobLogs('owner', 'repo', $jobId)
Actions::rerunJob('owner', 'repo', $jobId)
```

### Artifacts

[](#artifacts)

```
Actions::listArtifactsForRepository('owner', 'repo')
Actions::listArtifactsForWorkflowRun('owner', 'repo', $runId)
Actions::getArtifact('owner', 'repo', $artifactId)
Actions::downloadArtifact('owner', 'repo', $artifactId)  // Returns ZIP content
Actions::deleteArtifact('owner', 'repo', $artifactId)
```

DTOs
----

[](#dtos)

Clean, typed objects for everything:

```
// WorkflowRun
$run->id                    // int
$run->name                  // string
$run->status                // queued|in_progress|completed
$run->conclusion            // success|failure|cancelled|null
$run->headBranch            // string
$run->event                 // push|pull_request|etc
$run->runNumber             // int
$run->htmlUrl               // string
$run->isCompleted()         // bool
$run->wasSuccessful()       // bool
$run->wasFailed()           // bool

// Workflow
$workflow->id               // int
$workflow->name             // string
$workflow->path             // string (.github/workflows/ci.yml)
$workflow->state            // active|disabled
$workflow->isActive()       // bool

// Artifact
$artifact->id               // int
$artifact->name             // string
$artifact->sizeInBytes      // int
$artifact->sizeInMb()       // float
$artifact->expired          // bool
$artifact->isExpired()      // bool
$artifact->createdAt        // DateTime
$artifact->expiresAt        // DateTime|null

// Job
$job->id                    // int
$job->name                  // string
$job->status                // queued|in_progress|completed
$job->conclusion            // success|failure|cancelled|null
$job->steps                 // array
$job->isCompleted()         // bool
$job->wasSuccessful()       // bool
```

Real-World Examples
-------------------

[](#real-world-examples)

### Automated Artifact Cleanup (Cron Job)

[](#automated-artifact-cleanup-cron-job)

```
// Run daily: php artisan schedule:run
Schedule::call(function () {
    $repos = ['your-org/api', 'your-org/frontend', 'your-org/mobile'];

    foreach ($repos as $repo) {
        $artifacts = Actions::listArtifactsForRepository($repo);

        // Delete artifacts older than 7 days
        $artifacts->filter(fn($a) => $a->createdAt->diffInDays() > 7)
            ->each(fn($a) => Actions::deleteArtifact($repo, $a->id));
    }
})->daily();
```

### CI Health Monitoring

[](#ci-health-monitoring)

```
// Monitor all workflows
$workflows = Actions::listWorkflows('your-org/your-repo');

foreach ($workflows as $workflow) {
    if (!$workflow->isActive()) continue;

    $runs = Actions::listWorkflowRuns('your-org/your-repo', [
        'workflow_id' => $workflow->id,
    ]);

    $recentRuns = $runs->take(20);
    $failures = $recentRuns->filter(fn($r) => $r->wasFailed())->count();

    if ($failures > 10) {
        alert("Workflow {$workflow->name} is failing frequently");
    }
}
```

### Smart Retry Logic

[](#smart-retry-logic)

```
// Only retry transient failures
$run = Actions::getWorkflowRun('your-org/your-repo', $runId);

if ($run->wasFailed()) {
    $jobs = Actions::listJobsForWorkflowRun('your-org/your-repo', $runId);

    // Check if failures look transient (network, timeout)
    $transient = $jobs->filter(function ($job) {
        return $job->wasFailed() &&
               str_contains($job->conclusion, 'timeout') ||
               str_contains($job->conclusion, 'network');
    });

    if ($transient->isNotEmpty()) {
        Actions::rerunFailedJobs('your-org/your-repo', $runId);
    }
}
```

Framework Agnostic
------------------

[](#framework-agnostic)

Works with any PHP framework:

```
// Laravel
use ConduitUI\Action\Facades\Actions;

// Standalone
use ConduitUI\Action\Services\ActionsService;
use ConduitUI\Connector\GitHub;

$github = new GitHub(token: $_ENV['GITHUB_TOKEN']);
$actions = new ActionsService($github);
```

Related Packages
----------------

[](#related-packages)

Part of the [Conduit UI](https://github.com/conduit-ui) ecosystem:

- [conduit-ui/commit](https://github.com/conduit-ui/commit) - Commit history analysis
- [conduit-ui/pr](https://github.com/conduit-ui/pr) - Pull request automation
- [conduit-ui/issue](https://github.com/conduit-ui/issue) - Issue management
- [conduit-ui/connector](https://github.com/conduit-ui/connector) - GitHub API client

Enterprise Support
------------------

[](#enterprise-support)

Managing CI/CD at scale across dozens of repos? We provide:

- Custom workflow automation
- Cost optimization audits
- Dedicated support with SLA

Contact: [Conduit UI](https://github.com/conduit-ui)

Testing
-------

[](#testing)

```
composer test
composer analyse
composer format
```

License
-------

[](#license)

MIT License - see [LICENSE](LICENSE.md)

###  Health Score

17

—

LowBetter than 6% of packages

Maintenance49

Moderate activity, may be stable

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity12

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/a6bb27de88a541a632427686306c8fc56366d72582f6a3316d20500efe7971f3?d=identicon)[conduit-ui](/maintainers/conduit-ui)

---

Top Contributors

[![jordanpartridge](https://avatars.githubusercontent.com/u/9040417?v=4)](https://github.com/jordanpartridge "jordanpartridge (4 commits)")

### Embed Badge

![Health badge](/badges/conduit-ui-action/health.svg)

```
[![Health](https://phpackages.com/badges/conduit-ui-action/health.svg)](https://phpackages.com/packages/conduit-ui-action)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
