Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 122 additions & 0 deletions .github/workflows/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# FlightControl Demo GitHub Actions Workflows

This folder contains GitHub Actions workflows for automating the testing, building, and deployment of the FlightControl Demo firmware.

## Automated Workflow Overview

### PR Workflow (`pr-workflow.yaml`)

Triggered in the following scenarios:
- When a pull request is opened, reopened, or updated (synchronize) against the `master` branch
- Manually from the GitHub Actions tab

This workflow has three sequential jobs:

1. **Test**: Runs unit tests using CMake
2. **Compile**: Compiles the firmware for the BSOM platform
3. **Flash**: Flashes the compiled firmware to a test device

Each job only runs if the previous job succeeds, providing a complete validation pipeline for pull requests.

### Release Workflow (`release-workflow.yaml`)

Triggered in the following scenarios:
- When a PR is merged to `master` (note: closing without merging won't trigger the release)
- When code is pushed directly to `master`
- Manually from the GitHub Actions tab

This workflow has two sequential jobs:

1. **Release**:
- Compiles the firmware with auto-versioning
- Commits the updated version file
- Creates a GitHub release with the firmware binary and debug information

2. **Upload**:
- Uploads the firmware to the Particle cloud for OTA updates to production devices
- Only runs if the firmware version was updated in the previous step

## Individual Manual Workflows

These workflows can only be triggered manually from the GitHub Actions tab and are designed for testing individual steps before opening a PR.

### Manual Test (`manual-test.yaml`)
Runs the unit tests on a specific branch.
- **Inputs**:
- Branch to test (optional)

### Manual Compile (`manual-compile.yaml`)
Compiles the firmware on a specific branch.
- **Inputs**:
- Branch to compile (optional)
- **Outputs**:
- Firmware binary as an artifact

### Manual Flash (`manual-flash.yaml`)
Flashes a device with compiled firmware.
- **Inputs**:
- Device ID (optional, defaults to test device)
- Use latest artifact (yes/no)
- **Notes**:
- Can use the firmware from the latest manual-compile run or compile a new binary

### Manual Release (`manual-release.yaml`)
Creates a test release without committing version changes.
- **Inputs**:
- Branch to release (optional)
- Force version increment (yes/no)
- Custom release notes (optional)
- **Notes**:
- Creates a GitHub prerelease with '-manual' tag suffix
- Doesn't commit version changes back to the repository

### Manual Upload (`manual-upload.yaml`)
Uploads a firmware binary to Particle cloud.
- **Inputs**:
- Product ID (optional)
- Firmware version (required)
- Release title (optional)
- Use release artifact (yes/no)
- **Notes**:
- Can use the firmware from the latest manual-release run or compile a new binary

## Manual Workflow Triggering (Main Workflows)

The main workflows can also be triggered manually from the GitHub Actions tab:

1. **PR Workflow**:
- Optional input for the reason for manual testing

2. **Release Workflow**:
- Option to control version increment (yes/no)
- Custom release notes field that overrides the auto-generated ones

## Required Secrets

The workflows require the following secrets to be configured in your GitHub repository:

- `PARTICLE_ACCESS_TOKEN`: Particle cloud API token for uploading firmware
- `PARTICLE_USER_LEVEL_ACCESS_TOKEN`: Particle token for flashing individual test devices
- `PARTICLE_TEST_DEVICE_ID`: ID of the test device to flash during PR testing
- `PARTICLE_PRODUCT_ID`: ID of the Particle product for production releases

## Event Flow

1. **When opening a PR to master**:
- PR Workflow runs (test → compile → flash)
- This validates the changes before they're merged

2. **When merging a PR to master**:
- Release Workflow runs (compile/release → upload)
- This creates a new version, GitHub release, and deploys to Particle

3. **When pushing directly to master**:
- Release Workflow runs (same as merging a PR)
- This is for quick changes that don't require a PR

## Usage Notes

1. For initial testing, use the individual manual workflows to check each step separately
2. Once confident, open a PR to trigger the full PR workflow
3. After reviewing and approving, merge the PR to trigger the release workflow
4. Manual workflows provide a way to test specific stages of the pipeline in isolation
36 changes: 36 additions & 0 deletions .github/workflows/manual-compile.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Manual Compile

# This workflow can only be triggered manually
on:
workflow_dispatch:
inputs:
branch:
description: 'Branch to compile'
required: false
default: ''
type: string

jobs:
compile:
name: Compile Firmware
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive
ref: ${{ github.event.inputs.branch || github.ref }}

- name: Compile application
id: compile
uses: particle-iot/compile-action@9dbe1eb567c6268f1baa7458217d5d6e5553850d
with:
particle-platform-name: 'bsom'
device-os-version: 6.2.1

- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: firmware-binary
path: ${{ steps.compile.outputs.firmware-path }}
retention-days: 1
66 changes: 66 additions & 0 deletions .github/workflows/manual-flash.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
name: Manual Flash

# This workflow can only be triggered manually
on:
workflow_dispatch:
branch:
description: 'Branch to compile'
required: false
default: ''
type: string
inputs:
device_id:
description: 'Device ID to flash (defaults to test device)'
required: false
default: ''
type: string
use_latest_artifact:
description: 'Use latest uploaded artifact? (yes/no)'
required: false
default: 'yes'
type: string

jobs:
flash:
name: Flash Device
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive
ref: ${{ github.event.inputs.branch || github.ref }}

- name: Compile firmware
id: compile
if: github.event.inputs.use_latest_artifact != 'yes'
uses: particle-iot/compile-action@9dbe1eb567c6268f1baa7458217d5d6e5553850d
with:
particle-platform-name: 'bsom'
device-os-version: 6.2.1

- name: Download latest firmware artifact
if: github.event.inputs.use_latest_artifact == 'yes'
uses: dawidd6/action-download-artifact@v3
with:
workflow: manual-compile.yaml
name: firmware-binary
path: ./firmware

- name: Find firmware binary
id: find_binary
run: |
if [ "${{ github.event.inputs.use_latest_artifact }}" == "yes" ]; then
FIRMWARE=$(find ./firmware -name "*.bin" -type f | head -n 1)
else
FIRMWARE="${{ steps.compile.outputs.firmware-path }}"
fi
echo "Using firmware: $FIRMWARE"
echo "firmware-path=$FIRMWARE" >> $GITHUB_OUTPUT

- name: Flash device
uses: zradlicz/flash-device-action@fef2be3306f8a1fa40c75c832e9127513d973f3a
with:
particle-access-token: ${{ secrets.PARTICLE_USER_LEVEL_ACCESS_TOKEN }}
device-id: ${{ github.event.inputs.device_id || secrets.PARTICLE_TEST_DEVICE_ID }}
firmware-path: ${{ steps.find_binary.outputs.firmware-path }}
71 changes: 71 additions & 0 deletions .github/workflows/manual-release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: Manual Release

# This workflow can only be triggered manually
on:
workflow_dispatch:
inputs:
branch:
description: 'Branch to release'
required: false
default: ''
type: string
force_version_increment:
description: 'Force version increment'
required: false
default: 'yes'
type: string
release_notes:
description: 'Custom release notes'
required: false
type: string

jobs:
release:
name: Create Release
runs-on: ubuntu-latest
outputs:
firmware-path: ${{ steps.compile.outputs.firmware-path }}
firmware-version: ${{ steps.compile.outputs.firmware-version }}
firmware-version-updated: ${{ steps.compile.outputs.firmware-version-updated }}
release-url: ${{ steps.release.outputs.html_url }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.event.inputs.branch || github.ref }}

- name: Compile application
id: compile
uses: particle-iot/compile-action@v1
with:
particle-platform-name: 'bsom'
auto-version: ${{ github.event.inputs.force_version_increment == 'yes' }}
device-os-version: 6.1.1

- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: release-artifacts
path: |
${{ steps.compile.outputs.firmware-path }}
${{ steps.compile.outputs.target-path }}

- name: Create archive of target directory
if: steps.compile.outputs.firmware-version-updated == 'true'
run: |
tar -czf debug-objects.tar.gz ${{ steps.compile.outputs.target-path }}

- name: Create GitHub release
id: release
if: steps.compile.outputs.firmware-version-updated == 'true'
uses: ncipollo/release-action@v1
with:
artifacts: ${{ steps.compile.outputs.firmware-path }},debug-objects.tar.gz
generateReleaseNotes: ${{ github.event.inputs.release_notes == '' }}
body: ${{ github.event.inputs.release_notes }}
name: "Firmware v${{ steps.compile.outputs.firmware-version }} (Manual)"
tag: "v${{ steps.compile.outputs.firmware-version }}-manual"
commit: ${{ github.sha }}
token: ${{ secrets.GITHUB_TOKEN }}
prerelease: true
46 changes: 46 additions & 0 deletions .github/workflows/manual-test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Manual Test

# This workflow can only be triggered manually
on:
workflow_dispatch:
inputs:
branch:
description: 'Branch to test'
required: false
default: ''
type: string

jobs:
test:
name: Run Tests
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive
ref: ${{ github.event.inputs.branch || github.ref }}

- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y cmake build-essential

- name: Create build directory
run: mkdir -p build

- name: Configure CMake
run: cd build && cmake ..

- name: Build
run: cd build && cmake --build .

- name: Run tests
run: |
TEST_EXECUTABLE=$(find build -name "unit_tests" -type f -executable)
if [ -n "$TEST_EXECUTABLE" ]; then
$TEST_EXECUTABLE
else
echo "Test executable not found!"
exit 1
fi
Loading
Loading