Skip to content

Commit e7fbdb0

Browse files
authored
Merge branch 'main' into feature/ubuntu-26.04
2 parents 93ce685 + ea82a10 commit e7fbdb0

13 files changed

Lines changed: 405 additions & 45 deletions

.devcontainer/cpp/devcontainer-metadata.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
"marus25.cortex-debug@1.12.1",
1010
"mhutchie.git-graph@1.30.0",
1111
"ms-vscode.cmake-tools@1.22.28",
12-
"ms-vscode.cpptools@1.31.3",
13-
"ms-vsliveshare.vsliveshare@1.0.5959",
14-
"sonarsource.sonarlint-vscode@4.45.0"
12+
"ms-vscode.cpptools@1.31.4",
13+
"ms-vsliveshare.vsliveshare@1.1.122",
14+
"sonarsource.sonarlint-vscode@5.0.0"
1515
],
1616
"settings": {
1717
"C_Cpp.intelliSenseEngine": "disabled",

.devcontainer/cpp/devcontainer.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,16 @@
3636
"extensions": [
3737
"alexkrechik.cucumberautocomplete@3.1.0",
3838
"github.copilot@1.388.0",
39-
"github.vscode-github-actions@0.31.2",
40-
"github.vscode-pull-request-github@0.132.2",
39+
"github.vscode-github-actions@0.31.3",
40+
"github.vscode-pull-request-github@0.134.0",
4141
"jetmartin.bats@0.1.10",
4242
"kherring.bats-test-runner@0.1.3",
4343
"mhutchie.git-graph@1.30.0",
4444
"ms-azuretools.vscode-docker@2.0.0",
4545
"ms-playwright.playwright@1.1.17",
4646
"ms-vscode.cmake-tools@1.22.28",
47-
"ms-vscode.cpptools@1.31.3",
48-
"sonarsource.sonarlint-vscode@4.45.0",
47+
"ms-vscode.cpptools@1.31.4",
48+
"sonarsource.sonarlint-vscode@5.0.0",
4949
"usernamehw.errorlens@3.28.0"
5050
]
5151
}

.devcontainer/rust/devcontainer-metadata.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
"vscode": {
77
"extensions": [
88
"mhutchie.git-graph@1.30.0",
9-
"ms-vsliveshare.vsliveshare@1.0.5959",
10-
"rust-lang.rust-analyzer@0.3.2836",
9+
"ms-vsliveshare.vsliveshare@1.1.119",
10+
"rust-lang.rust-analyzer@0.3.2845",
1111
"tamasfe.even-better-toml@0.21.2",
1212
"usernamehw.errorlens@3.28.0"
1313
]

.devcontainer/rust/devcontainer.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@
1919
},
2020
"extensions": [
2121
"github.copilot@1.388.0",
22-
"github.vscode-github-actions@0.31.2",
23-
"github.vscode-pull-request-github@0.132.2",
22+
"github.vscode-github-actions@0.31.3",
23+
"github.vscode-pull-request-github@0.134.0",
2424
"jetmartin.bats@0.1.10",
2525
"kherring.bats-test-runner@0.1.3",
2626
"mhutchie.git-graph@1.30.0",
2727
"ms-azuretools.vscode-docker@2.0.0",
28-
"rust-lang.rust-analyzer@0.3.2836",
29-
"sonarsource.sonarlint-vscode@4.45.0",
28+
"rust-lang.rust-analyzer@0.3.2845",
29+
"sonarsource.sonarlint-vscode@5.0.0",
3030
"tamasfe.even-better-toml@0.21.2",
3131
"usernamehw.errorlens@3.28.0"
3232
]

.github/workflows/release-build.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ jobs:
118118
generate-documents:
119119
name: 📄 Documentation
120120
uses: ./.github/workflows/wc-document-generation.yml
121+
with:
122+
is-release: true
121123
permissions:
122124
contents: read
123125

@@ -140,7 +142,7 @@ jobs:
140142
- name: Upload documents to release
141143
run: |
142144
set -Eeuo pipefail
143-
gh release upload "${REF_NAME}" ./*.pdf
145+
gh release upload "${REF_NAME}" ./*.pdf ./*.sbdl
144146
env:
145147
GH_REPO: ${{ github.repository }}
146148
GH_TOKEN: ${{ github.token }}

.github/workflows/wc-document-generation.yml

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ name: Document Generation
33

44
on:
55
workflow_call:
6+
inputs:
7+
is-release:
8+
description: Whether the workflow is running for a release.
9+
default: false
10+
type: boolean
611

712
permissions: {}
813

@@ -22,19 +27,54 @@ jobs:
2227
- name: Install dependencies
2328
run: |
2429
set -Eeuo pipefail
30+
2531
sudo apt-get update && sudo apt-get install --no-install-recommends -y plantuml
26-
python -m pip install gherkin-official==38.0.0 sbdl==1.21.3
32+
python -m pip install sbdl==1.22.7
2733
- name: Build & Validate SBDL model
28-
run: sbdl -m compile test/cpp/features/*.feature > amp-devcontainer.sbdl
29-
- name: Generate SRS document
30-
run: sbdl -m template-fill --template docs/templates/software-requirements-specification.md.j2 amp-devcontainer.sbdl > software-requirements-specification.md
31-
- uses: docker://pandoc/extra:3.9.0.0-ubuntu@sha256:72afa9c8d3300e5f10c9c4330e101725687f2179bffd912fb859c6d2ae85de62
34+
run: sbdl -m compile test/cpp/integration-tests.bats test/cpp/features/*.feature > amp-devcontainer.sbdl
35+
- name: Create document control context
36+
env:
37+
GITHUB_REF_NAME: ${{ github.ref_name }}
38+
IS_RELEASE: ${{ inputs.is-release }}
39+
run: |
40+
set -Eeuo pipefail
41+
42+
cat > document-control.sbdl <<SBDL
43+
#!sbdl
44+
doc_control is aspect {
45+
description is "Document control metadata"
46+
custom:version is "$(jq -r '.["."]' .release-please-manifest.json)"
47+
custom:generated_at is "[@DATE]"
48+
custom:git_sha is "[@GIT_COMMIT_HASH]"
49+
custom:git_ref is "${GITHUB_REF_NAME}"
50+
custom:sbdl_compiler_version is "[@COMPILER_VERSION]"
51+
custom:sbdl_dsl_version is "[@DSL_VERSION]"
52+
custom:is_release is "${IS_RELEASE}"
53+
}
54+
SBDL
55+
- name: 📄 Generate SRS document
56+
run: sbdl -m template-fill --set-config template_extensions_file docs/templates/jinja-extensions.py --template docs/templates/software-requirements-specification.md.j2 amp-devcontainer.sbdl document-control.sbdl > software-requirements-specification.md
57+
- name: 🧪 Generate STP document
58+
run: sbdl -m template-fill --set-config template_extensions_file docs/templates/jinja-extensions.py --template docs/templates/software-test-plan.md.j2 amp-devcontainer.sbdl document-control.sbdl > software-test-plan.md
59+
- name: 🧩 Generate RTM document
60+
run: sbdl -m template-fill --set-config template_extensions_file docs/templates/jinja-extensions.py --template docs/templates/requirements-traceability-matrix.md.j2 amp-devcontainer.sbdl document-control.sbdl > requirements-traceability-matrix.md
61+
- name: 📄 Generate SRS PDF
62+
uses: docker://pandoc/extra:3.9.0.0-ubuntu@sha256:72afa9c8d3300e5f10c9c4330e101725687f2179bffd912fb859c6d2ae85de62
3263
with:
3364
args: --template eisvogel --syntax-highlighting idiomatic --number-sections --output software-requirements-specification.pdf software-requirements-specification.md
65+
- name: 🧪 Generate STP PDF
66+
uses: docker://pandoc/extra:3.9.0.0-ubuntu@sha256:72afa9c8d3300e5f10c9c4330e101725687f2179bffd912fb859c6d2ae85de62
67+
with:
68+
args: --template eisvogel --syntax-highlighting idiomatic --number-sections --output software-test-plan.pdf software-test-plan.md
69+
- name: 🧩 Generate RTM PDF
70+
uses: docker://pandoc/extra:3.9.0.0-ubuntu@sha256:72afa9c8d3300e5f10c9c4330e101725687f2179bffd912fb859c6d2ae85de62
71+
with:
72+
args: --template eisvogel --syntax-highlighting idiomatic --number-sections --output requirements-traceability-matrix.pdf requirements-traceability-matrix.md
3473
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
3574
with:
3675
name: documents
3776
path: |
3877
*.pdf
3978
*.sbdl
79+
!document-control.sbdl
4080
retention-days: 2

docs/templates/jinja-extensions.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from datetime import datetime
2+
3+
def strftime_filter(value, fmt):
4+
if value.endswith('Z'):
5+
value = value[:-1] + '+00:00'
6+
7+
return datetime.fromisoformat(value).strftime(fmt)
8+
9+
filters = { 'strftime': strftime_filter }
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
| Property | Value |
2+
|-------------------|---------------------------------------------------------------------------------------------------------------------------|
3+
| Document version | {{ sbdl['doc_control']['custom:version'] }} |
4+
| Generation date | {{ sbdl['doc_control']['custom:generated_at'] | strftime('%Y-%m-%d') }} |
5+
| Source revision | {{ sbdl['doc_control']['custom:git_sha'] }} |
6+
| Source branch/tag | {{ sbdl['doc_control']['custom:git_ref'] }} |
7+
| Model | SBDL {{ sbdl['doc_control']['custom:sbdl_compiler_version'] }} (DSL {{ sbdl['doc_control']['custom:sbdl_dsl_version'] }}) |
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{% macro reencode(text) -%}
2+
{{ text.encode('utf-8').decode('unicode_escape') }}
3+
{%- endmacro -%}
4+
5+
{%- macro strip_gherkin_prefix(text) -%}
6+
{{ text | replace('Rule: ', '') | replace('Feature: ', '') }}
7+
{%- endmacro -%}
8+
9+
{%- macro strip_bats_syntax(text) -%}
10+
{{ text | replace('@test "', '') | replace('" \{', '') | replace('" {', '') }}
11+
{%- endmacro -%}
12+
13+
{%- macro display_short(text) -%}
14+
{{ text[:60] }}
15+
{%- endmacro %}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
---
2+
title: "Requirements traceability matrix for amp-devcontainer"
3+
author: ["@rjaegers"]
4+
colorlinks: true
5+
date: "{{ sbdl['doc_control']['custom:generated_at'] | strftime('%Y-%m-%d') }}"
6+
keywords: [Traceability, Requirements, RTM, amp-devcontainer]
7+
lang: "en"
8+
titlepage: true
9+
titlepage-color: "0B5ED7"
10+
titlepage-text-color: "FFFFFF"
11+
titlepage-rule-color: "FFFFFF"
12+
titlepage-rule-height: 2
13+
toc: true
14+
toc-own-page: true
15+
header-includes:
16+
- \AtEndDocument{\label{lastpage}}
17+
{%- if sbdl['doc_control']['custom:is_release'] != 'true' %}
18+
watermark: "DRAFT"
19+
{%- endif %}
20+
footer-right: "\\thepage \\hspace{1pt} of \\pageref*{lastpage}"
21+
...
22+
23+
{% import "partials/text-utilities.j2" as utils %}
24+
25+
# Introduction
26+
27+
## Purpose
28+
29+
This document provides a requirements traceability matrix (RTM) for amp-devcontainer. It maps each requirement to its associated verification tests, providing evidence of test coverage across the system.
30+
31+
## Abstract
32+
33+
amp-devcontainer is a set of [devcontainers](https://containers.dev/) tailored towards modern, embedded, software development. This traceability matrix traces requirements from the *Software Requirements Specification (SRS)* to their corresponding verification tests as enumerated in the *Software Test Plan (STP)*.
34+
35+
## Document Control
36+
37+
{% include "partials/document-control.md.j2" with context %}
38+
39+
This document is generated from a formal model defined in [sbdl](https://sbdl.dev) and versioned alongside the source code in Git.
40+
The authoritative source of change history is the [Git log](https://github.com/philips-software/amp-devcontainer/commits/) of the source material from which the model is built.
41+
42+
# Traceability Matrix
43+
{%- for id, item in sbdl.items() %}
44+
{%- if item.type == 'aspect' and 'custom:title' in item %}
45+
46+
## {{ utils.reencode(utils.strip_gherkin_prefix(item['custom:title'])) }}
47+
48+
| Requirement | Test | Status |
49+
|-------------|------|--------|
50+
51+
{%- if 'requirement' in item %}
52+
{%- for req_ref in item.requirement %}
53+
{%- set req = sbdl[req_ref.identifier] %}
54+
{%- set req_name = utils.reencode(utils.strip_gherkin_prefix(req['custom:title'])) | trim %}
55+
56+
{%- set ns_tests = namespace(test_list=[]) -%}
57+
58+
{%- for test_id, test_elem in sbdl.items() -%}
59+
{%- if test_elem.type == 'test' -%}
60+
{%- if 'requirement' in test_elem -%}
61+
{%- for test_req_ref in test_elem.requirement if test_req_ref.identifier == req_ref.identifier -%}
62+
{%- set _ = ns_tests.test_list.append(test_id) -%}
63+
{%- endfor -%}
64+
{%- endif -%}
65+
{%- endif -%}
66+
{%- endfor -%}
67+
68+
{%- if ns_tests.test_list -%}
69+
{%- for test_id in ns_tests.test_list %}
70+
{%- set test_name = utils.strip_bats_syntax(sbdl[test_id]['custom:title']) | trim %}
71+
| {{ utils.display_short(req_name) }} | {{ test_id }}: {{ utils.display_short(test_name) }} | Traced |
72+
{%- endfor -%}
73+
{%- else %}
74+
| {{ utils.display_short(req_name) }} | — | **Not covered** |
75+
{%- endif -%}
76+
77+
{%- endfor %}
78+
{%- endif %}
79+
{%- endif %}
80+
{%- endfor %}
81+
82+
# Coverage Summary
83+
84+
{%- set ns_summary = namespace(total_reqs=0, covered_reqs=0, total_tests=0) -%}
85+
86+
{%- for elem_id, elem in sbdl.items() -%}
87+
{%- if elem.type == 'requirement' -%}
88+
{%- set ns_summary.total_reqs = ns_summary.total_reqs + 1 -%}
89+
90+
{%- set ns_covered = namespace(is_covered=false) -%}
91+
{%- for test_id, test_elem in sbdl.items() -%}
92+
{%- if test_elem.type == 'test' and 'requirement' in test_elem -%}
93+
{%- for req_ref in test_elem.requirement if req_ref.identifier == elem_id -%}
94+
{%- set ns_covered.is_covered = true -%}
95+
{%- endfor -%}
96+
{%- endif -%}
97+
{%- endfor -%}
98+
99+
{%- if ns_covered.is_covered -%}
100+
{%- set ns_summary.covered_reqs = ns_summary.covered_reqs + 1 -%}
101+
{%- endif -%}
102+
103+
{%- endif -%}
104+
105+
{%- if elem.type == 'test' -%}
106+
{%- set ns_summary.total_tests = ns_summary.total_tests + 1 -%}
107+
{%- endif -%}
108+
{%- endfor %}
109+
110+
| Metric | Value |
111+
|---|---|
112+
| Total requirements | {{ ns_summary.total_reqs }} |
113+
| Requirements with tests | {{ ns_summary.covered_reqs }} |
114+
| Requirements without tests | {{ ns_summary.total_reqs - ns_summary.covered_reqs }} |
115+
| Total tests | {{ ns_summary.total_tests }} |

0 commit comments

Comments
 (0)