- manual triggers (
workflow_dispatch), - transferring files between jobs using artifacts,
- avoiding race conditions by ordering jobs with
needs, - and how to skip CI when pushing changes.
1. Initial demo workflow (manual trigger)
This workflow, namedDemo-2, runs only when manually triggered from the Actions tab (workflow_dispatch). It contains a single build job that creates hello.txt:
push or other events.
2. Understanding existing CI workflows and skipping CI on push
If your repository already has another workflow that triggers onpush, pushing commits can inadvertently trigger that existing workflow. To avoid triggering push-based workflows while you push changes, include [skip CI] or [ci skip] in your commit message.
Include
[skip CI] (or [ci skip]) in the commit message to prevent workflows that trigger on push from running for that commit.push and manual dispatch looks like this:
3. Adding a second job (and the inter-job file-sharing problem)
Next, we add atest job that expects to read hello.txt created by the build job:
test job will typically fail with:
4. Use artifacts to transfer files between jobs
To share files between jobs, useactions/upload-artifact in the producing job and actions/download-artifact in the consuming job. These actions are available in the GitHub Marketplace (search for “artifact”).

build and download it in test:
actions/upload-artifact@v4creates a named artifact (hello-file) that persists for the run.actions/download-artifact@v4finds that artifact by name and restores the file(s) into the runner workspace.
5. Race condition when jobs run in parallel
By default, jobs that have no explicit dependency may run in parallel. Iftest starts before build has finished uploading the artifact, the download will fail with an artifact-not-found error:
test job started before build finished:

6. Make one job depend on another with needs
To ensuretest runs only after build completes, add the needs keyword to the test job:
needs: buildguaranteestestwill not start untilbuildhas completed (and the artifact is uploaded).needsaccepts an array when a job depends on multiple jobs, for example:needs: [build, job-xyz].- If you specify a non-existent job in
needs, the workflow will fail to parse or run.
Do not reference job names that don’t exist in
needs (for example: needs: [build, job-xyz] where job-xyz is not defined). That causes the workflow to fail to parse or execute.7. Successful artifact download logs (example)
Whentest runs after build finishes, the download-artifact step will find and download the artifact. Example logs show the download flow and the restored file:
Summary and quick reference
- Jobs run on separate runners and do not share the filesystem by default.
- Use
actions/upload-artifact@v4to upload files from a job. - Use
actions/download-artifact@v4to download artifacts in subsequent jobs. - Use
needsto serialize jobs so a job waits for one or more other jobs to finish. - Use
[skip CI]or[ci skip]in commit messages to avoid triggering push-based workflows.
| Feature | Purpose | Example |
|---|---|---|
| Manual trigger | Run workflow from Actions UI | on: workflow_dispatch |
| Upload artifact | Persist files from a job | uses: actions/upload-artifact@v4 |
| Download artifact | Restore files in another job | uses: actions/download-artifact@v4 |
| Job dependency | Ensure job order | needs: build or needs: [build, job-xyz] |
| Skip CI on push | Prevent push workflows from running | include [skip CI] in commit message |
Links and references
- GitHub Actions: upload-artifact action (marketplace)
- GitHub Actions: download-artifact action (marketplace)
- GitHub Actions documentation — workflow syntax for GitHub Actions
- GitHub Marketplace (search: artifact)
needs.