Skip to content

About

No description, website, or topics provided.

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

EmbeddedCI Submit Job

GitHub Action that submits jobs to the EmbeddedCI server in two modes:

  • YAML-only mode: send pipeline definition text.
  • Archive mode: send source bundle + embeddedci_yaml using multipart upload.

Usage

Ensure your workflow checks out the repository first. This action authenticates with the api_key input only, so the job needs no extra permissions: (unlike upload-artifact, which needs id-token: write).

How the modes differ:

  • Archive mode archives the contents of source_path and sends that archive to the server (with embeddedci_yaml for which pipeline file to use inside the bundle).
  • YAML-only mode sends nothing except the pipeline YAML. Use it when source files are publicly accessible via Git (or similar) as specified inside the YAML, so the server can fetch them without an upload from this action.

Archive mode (recommended for repo-based builds)

jobs:
  submit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: embeddedci-com/submit-job-action@v1
        with:
          api_key: ${{ secrets.EMBEDDEDCI_API_KEY }}
          source_path: .

YAML-only mode

jobs:
  submit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: embeddedci-com/submit-job-action@v1
        with:
          api_key: ${{ secrets.EMBEDDEDCI_API_KEY }}
          embeddedci_yaml: embeddedci.yaml

Inputs

Input Required Default Description
api_key Yes - API key for EmbeddedCI. Use secrets.EMBEDDEDCI_API_KEY.
api_url No https://api.embeddedci.com EmbeddedCI server base URL. Override for self-hosted or staging. A value without a scheme gets https:// prepended.
source_path No empty Path to what should be uploaded in archive mode. You can pass a directory (including .) and the action creates the archive automatically, or pass an existing archive file (.tar.gz, .tgz, .tar, .zip).
embeddedci_yaml No empty Pipeline YAML path. In YAML-only mode this is the repo file path (defaults to embeddedci.yaml when omitted). In archive mode this optionally overrides auto-detection (embeddedci.yaml).
ref No branch name from GitHub context Ref associated with the submission. Auto-detected from GITHUB_HEAD_REF (PRs) or GITHUB_REF_NAME.
commit No GITHUB_SHA Commit SHA associated with the submission.

Examples

Custom pipeline file and API URL (YAML-only)

- uses: embeddedci-com/submit-job-action@v1
  with:
    api_key: ${{ secrets.EMBEDDEDCI_API_KEY }}
    api_url: https://ci.mycompany.com
    embeddedci_yaml: .embeddedci/job.yaml

Archive from current directory on-the-fly

- uses: embeddedci-com/submit-job-action@v1
  with:
    api_key: ${{ secrets.EMBEDDEDCI_API_KEY }}
    source_path: .

Archive from a specific directory on-the-fly

- uses: embeddedci-com/submit-job-action@v1
  with:
    api_key: ${{ secrets.EMBEDDEDCI_API_KEY }}
    source_path: firmware/

Override pipeline path inside archive (optional)

- uses: embeddedci-com/submit-job-action@v1
  with:
    api_key: ${{ secrets.EMBEDDEDCI_API_KEY }}
    source_path: firmware/
    embeddedci_yaml: ci/embeddedci.yaml

Explicit ref and commit metadata (optional)

- uses: embeddedci-com/submit-job-action@v1
  with:
    api_key: ${{ secrets.EMBEDDEDCI_API_KEY }}
    source_path: .
    ref: ${{ github.ref_name }}
    commit: ${{ github.sha }}

Use a prebuilt archive file (optional)

- uses: embeddedci-com/submit-job-action@v1
  with:
    api_key: ${{ secrets.EMBEDDEDCI_API_KEY }}
    source_path: repo.tar.gz

Outputs

Outputs are only set when the server includes the matching field in its response; an unset output reads as an empty string in later steps.

Output Description
job_id Set when the server returns a job id in the response.
job_status Set when the server returns a job status.
job_builds JSON-encoded builds payload when present.
source_metadata JSON-encoded source metadata when present.

Archive Preparation Recommendations

  • Prefer passing a directory path (for example .) and let the action archive it automatically.
  • Exclude large/unneeded files such as .git, build outputs, and caches when creating archives manually.
  • Include embeddedci.yaml in the archive root when using default auto-detection.
  • Set embeddedci_yaml when your pipeline file lives at a custom archive path.

Development

npm install
npm run build

The built action is in dist/. Commit dist/ so the action works when used from GitHub.

Actions in this repository

Action Use it for
embeddedci-com/submit-job-action@v1 Submit a pipeline or source archive to the EmbeddedCI build system.
embeddedci-com/submit-job-action/upload-artifact@v1 Publish a firmware you built yourself, so it appears in the BenchPod flash dropdown.
embeddedci-com/submit-job-action/emi@v1 Run EMI analysis on a KiCad or Gerber board and gate the build on the findings.

upload-artifact

Records a build you produced in your own workflow as a GitHub-sourced build on embeddedci.com and attaches the firmware to it. No BenchPod is touched, so it is safe to run on every push.

permissions:
  id-token: write        # required: the action authenticates with the job's OIDC token
  contents: read

steps:
  - uses: actions/checkout@v5
  # ... your existing build ...
  - uses: embeddedci-com/submit-job-action/upload-artifact@v1
    with:
      firmware: build/app.elf
      build_target: stm32f4
      openocd_target: target/stm32f4x.cfg
      swclk: "11"
      swdio: "12"
      efuse: "1"

The firmware's siblings (.elf / .bin / .hex / .uf2 with the same stem) are uploaded alongside it, and the wiring inputs pre-fill the web UI's flash dialog. The repository must be trusted in the EmbeddedCI web app under BenchPod → GitHub Actions; without that, or without id-token: write, the step fails with a message naming what is missing.

Set allow_missing_token: "true" to downgrade that failure to a skip — useful for pull requests from forks, which cannot mint an OIDC token.

Input Required Default Notes
firmware Yes - Path to the built firmware (.elf, .bin or .hex). Siblings with the same stem (.elf, .bin, .hex, .uf2) are uploaded too.
build_target No empty Platform id recorded against the build, for example stm32f4. Shown on the Builds page.
openocd_target No empty OpenOCD target config for the DUT, for example target/stm32f4x.cfg. Pre-fills the flash dialog.
swclk No empty LA channel (1-14) wired to SWCLK. Pre-fills the flash dialog.
swdio No empty LA channel (1-14) wired to SWDIO. Pre-fills the flash dialog.
nreset No empty true when the target's NRST is wired to the pod's reset pin (DUT header J1 pin 22). Leave empty when it is not wired. An LA channel number from older workflows is still accepted and read as "wired".
efuse No empty Target-power eFuse rail: 1 = internal 5 V, 2 = external.
name No server-side commit summary Build name shown in the web UI.
api_base No https://www.embeddedci.com EmbeddedCI base URL. When empty, the SDK reads BENCHPOD_API_BASE from the environment before falling back to the public server.
sdk_ref No empty Tag, branch or commit of embeddedci-python to install instead of the PyPI release (see below).
python_version No 3.12 Python that actions/setup-python installs for the upload step.
allow_missing_token No false true succeeds with a skip instead of failing when no OIDC token is available (for example a fork PR).
Output Description
build_id The embeddedci build id the artifacts were attached to. Empty when the upload was skipped by allow_missing_token.

The step installs the embeddedci SDK from PyPI (embeddedci==2.5.*). Set sdk_ref to a tag, branch or commit of embeddedci-python to install that instead, for example to try an unreleased fix.

Implementation note: this is a composite action wrapping the embeddedci-upload-build command from the embeddedci Python SDK, which is the same code path the pytest build_report fixture uses. Keeping one implementation avoids a second copy of the OIDC exchange and build API drifting from the server.

emi

Runs the EMI Analyzer's rules tier against a board committed to the repository, annotates the findings on the workflow run, and fails the build on the severity you choose. It takes seconds — this is the geometric tier, not a full-wave solve — so it is cheap enough for every push that touches the layout.

steps:
  - uses: actions/checkout@v5
  - uses: embeddedci-com/submit-job-action/emi@v1
    with:
      api_key: ${{ secrets.EMBEDDEDCI_API_KEY }}
      board: hardware/mainboard.kicad_pcb

Only run it when the layout actually changed, or it will re-analyse an unchanged board on every commit:

on:
  push:
    paths:
      - "hardware/**.kicad_pcb"

Auth is an API key, not the OIDC token upload-artifact uses. EMI runs are filed under the organisation that owns the key, so the credential has to identify a person rather than a repository. Generate one in the web app under Settings → API keys with the emi:analyze scope, and store it as a repository secret.

Input Default Notes
api_key required Needs the emi:analyze scope.
board required A .kicad_pcb, a zip of the KiCad project, or a zip of Gerbers + drill + IPC-D-356 netlist.
project repository name Boards accumulate under this name across commits, which is what makes a later comparison possible.
source_kind inferred kicad or gerber.
fail_on critical critical, warning, or none.
api_base https://www.embeddedci.com
timeout_seconds 300
summary true Write the findings table to the job summary.

Outputs run_id, board_id, project_id, critical, warning, info, and rules_json (a path to the downloaded findings, for a step that wants the detail).

fail_on: critical is the default deliberately. Gating on warnings sounds stricter but is worse in practice: a board of any real complexity carries warnings a human has already looked at and accepted, and a check that cries wolf on every push gets switched off within the week.

A Gerber upload must include an IPC-D-356 netlist. Gerbers carry no net information, so without it there is no way to tell a signal trace from its own ground pour — the server refuses the upload rather than analysing something meaningless.

Implementation note: a composite action calling the EMI REST API with curl and jq, both already on every runner. Unlike upload-artifact there is no SDK to wrap — nothing else implements this flow — so there is no second copy to drift, and no build step between editing emi/emi-analyze.sh and the change taking effect.

About

No description, website, or topics provided.

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages