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
5 changes: 5 additions & 0 deletions .github/workflows/wc-build-push-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,8 @@ jobs:
- uses: EnricoMi/publish-unit-test-result-action@3a74b2957438d0b6e2e61d67b05318aa25c9e6c6 # v2.20.0
with:
files: test-report-*.xml

generate-documents:
uses: ./.github/workflows/wc-document-generation.yml
permissions:
contents: read
38 changes: 38 additions & 0 deletions .github/workflows/wc-document-generation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
name: Document Generation

on:
workflow_call:

permissions:
contents: read

jobs:
generate-documents:
runs-on: ubuntu-latest
steps:
- uses: step-security/harden-runner@002fdce3c6a235733a90a27c80493a3241e56863 # v2.12.1
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- name: Install dependencies
run: |
set -Eeuo pipefail
sudo apt-get update && sudo apt-get install --no-install-recommends -y plantuml
python -m pip install gherkin-official==35.1.0 sbdl==1.16.4
- name: Generate requirements document
run: |
set -Eeuo pipefail
python docs/support/gherkin-to-csv.py test/cpp/features/*.feature
python -m csv-to-sbdl --identifier 0 --description 1 --skipheader rules.csv
sbdl -m template-fill --template docs/templates/requirements.template.md output.sbdl > requirements.md
- uses: docker://pandoc/extra:3.7.0@sha256:a703d335fa237f8fc3303329d87e2555dca5187930da38bfa9010fa4e690933a
with:
args: --template eisvogel --output requirements.pdf requirements.md
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: documents
path: requirements.pdf
retention-days: 2
75 changes: 75 additions & 0 deletions docs/support/gherkin-to-csv.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#!/usr/bin/env python3

import argparse
import csv
import os
import sys
from dataclasses import dataclass, asdict, fields
from typing import List
from gherkin.parser import Parser
from gherkin.token_scanner import TokenScanner

@dataclass
class Rule:
"""A class representing a rule extracted from a Gherkin feature file."""
identifier: str
description: str

@classmethod
def field_names(cls) -> List[str]:
return [f.name for f in fields(cls)]

def extract_rules_from_feature(file_path):
"""Parse a Gherkin feature file and extract the rules."""
try:
with open(file_path, 'r', encoding='utf-8') as file:
content = file.read()

parser = Parser()
feature_document = parser.parse(TokenScanner(content))
rules = []

if 'feature' in feature_document:
feature = feature_document['feature']

if 'children' in feature:
for child in feature['children']:
if 'rule' in child:
rule = child['rule']
rule_id = rule.get('name', '').strip()
description = rule.get('description', '').strip()
rules.append(Rule(
identifier=rule_id,
description=description
))

return rules
except Exception as e:
print(f"Error parsing {file_path}: {e}", file=sys.stderr)
return []

def main():
parser = argparse.ArgumentParser(description='Extract rules from Gherkin feature files and save to CSV')
parser.add_argument('feature_files', nargs='+', help='Paths to feature files')
parser.add_argument('--output', '-o', default='rules.csv', help='Output CSV file path')

args = parser.parse_args()
all_rules = []

for feature_path in args.feature_files:
if os.path.isfile(feature_path):
print(f"Processing {feature_path}")
rules = extract_rules_from_feature(feature_path)
all_rules.extend(rules)
else:
print(f"File not found: {feature_path}", file=sys.stderr)

with open(args.output, 'w', newline='', encoding='utf-8') as csvfile:
writer = csv.DictWriter(csvfile, fieldnames=Rule.field_names())
writer.writeheader()
writer.writerows([asdict(rule) for rule in all_rules])

print(f"Extracted {len(all_rules)} rules to {args.output}")

if __name__ == '__main__':
main()
45 changes: 45 additions & 0 deletions docs/templates/requirements.template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# amp-devcontainer requirement specification

## Introduction

### Purpose

This document describes the software system requirements for amp-devcontainer.

### Definitions of key words

The key words *MUST*, *MUST NOT*, *REQUIRED*, *SHALL*, *SHALL NOT*, *SHOULD*, *SHOULD NOT*, *RECOMMENDED*, *MAY*, and *OPTIONAL* in this document are to be interpreted as described in [RFC 2119](https://www.rfc-editor.org/rfc/rfc2119).

### Abstract

amp-devcontainer is a set of [devcontainers](https://containers.dev/) tailored towards modern, embedded, software development.

The containers may be used both for local development and continuous integration (ci).

### Terminology and Abbreviations

| Terminology and Abbreviations | Description/Definition |
|-------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------|
| ARM | A family of RISC architectures for computer processors and micro controllers, formerly an acronym for Advanced RISC Machines and originally Acorn RISC Machine |
| Continuous Integration (ci) | The practice of continuously merging developers work to a shared code-base; ideally including automation for build, test and deployment |
| ELF | Executable and Linkable Format, formerly named Extensible Linking Format |
| RISC | Reduced Instruction Set Computer |

## Requirements

{%- macro reencode(text) -%}
{{ text.encode('utf-8').decode('unicode_escape') }}
{%- endmacro -%}

{%- macro sbdl_id_to_header(text) -%}
{{ text.replace('_', ' ') }}
{%- endmacro -%}

{% for req_id, requirement in sbdl.items() %}
{% if requirement.type == 'requirement' %}
### {{ reencode(sbdl_id_to_header(req_id)) }}

{{ reencode(requirement.description) }}

{% endif %}
{% endfor %}
52 changes: 39 additions & 13 deletions test/cpp/features/compilation.feature
Original file line number Diff line number Diff line change
@@ -1,19 +1,45 @@
Feature: Compile source code into working software
Feature: Compilation

As a developer
To generate working software
Source code needs to be compiled successfully
As a software developer
To generate a working product
Source code needs to be compiled into working software

Scenario: Compile valid source code into working software targeting the host architecture
Rule: Compile for container host architecture and operating system
amp-devcontainer *SHALL* be able to compile valid source code into a working executable targeting the container host architecture and operating system.

Compiling valid source code into working software, able to run on the host architecture,
Compiling valid source code into working software, able to run on the container host architecture and operating system,
can be necessary in several scenarios; for example when:

- the host is the deployment target
- running tests on the host
- building plug-ins, extensions, code generators, or other additional tools that need to run on the host
- the container host is the deployment target
- running tests on the container host
- building plug-ins, extensions, code generators, or other additional tools that need to run on the container host

Given build configuration "gcc" is selected
And build preset "gcc" is selected
When the selected target is built
Then the output should contain "Build finished with exit code 0"
@flavor:cpp
Scenario: Compile valid source code into working software targeting the container host architecture
Given build configuration "gcc" is selected
And build preset "gcc" is selected
When the selected target is built
Then the output should contain "Build finished with exit code 0"

Rule: Compile for ARM Cortex target architecture
amp-devcontainer *SHALL* be able to compile valid source-code into a working ELF executable targeting the ARM Cortex architecture.

Compiling valid source-code into working ELF executables, able to run on the ARM Cortex architecture,
is a primary function for amp-devcontainer. It enables building firmware for micro-controllers based
on the ARM Cortex architecture.

Rule: Compile for Microsoft® Windows operating system
amp-devcontainer *SHALL* be able to compile valid source-code into a working executable targeting the Microsoft® Windows operating system.

Compiling valid source-code into working executables, able to run on the Microsoft® Windows operating system, can be necessary in several scenarios e.g.

- Cross platform code is written and needs to be compiled and deployed
- Executables needs to be deployed outside of container context to a host running the Microsoft® Windows operating system

Rule: Compilation cache
amp-devcontainer *SHOULD* be able to cache the results of a compilation to speed-up subsequent compilations.

Maintaining a compilation cache can be useful in both local and ci development scenarios. A compilation cache can provide benefits like:

- Reduce developer waiting time and context switches, [maintaining flow-state](https://azure.microsoft.com/en-us/blog/quantifying-the-impact-of-developer-experience/)
- Reduce CPU usage at the cost of more storage usage, potentially reducing energy consumption and cost for metered ci-systems
Loading