diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 33aa83a..b2ed165 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,3 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 +# © Crown Copyright 2025. This work has been developed by the National Digital Twin Programme and is legally attributed to the Department for Business and Trade (UK) as the governing entity. + # Please see the documentation for all configuration options: # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file diff --git a/.github/workflows/ci-pr.yml b/.github/workflows/ci-pr.yml index 579b471..232b929 100644 --- a/.github/workflows/ci-pr.yml +++ b/.github/workflows/ci-pr.yml @@ -1,3 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 +# © Crown Copyright 2025. This work has been developed by the National Digital Twin Programme and is legally attributed to the Department for Business and Trade (UK) as the governing entity. + name: CI on PR on: diff --git a/.github/workflows/conventional-commits.yml b/.github/workflows/conventional-commits.yml index 450c449..0d06d8d 100644 --- a/.github/workflows/conventional-commits.yml +++ b/.github/workflows/conventional-commits.yml @@ -1,3 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 +# © Crown Copyright 2025. This work has been developed by the National Digital Twin Programme and is legally attributed to the Department for Business and Trade (UK) as the governing entity. + name: PR Conventional Commit Validation on: diff --git a/.github/workflows/gitflow-branch-naming.yml b/.github/workflows/gitflow-branch-naming.yml index 93320b1..411ea14 100644 --- a/.github/workflows/gitflow-branch-naming.yml +++ b/.github/workflows/gitflow-branch-naming.yml @@ -1,3 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 +# © Crown Copyright 2025. This work has been developed by the National Digital Twin Programme and is legally attributed to the Department for Business and Trade (UK) as the governing entity. + name: GitFlow - Enforce Branch Naming Convention on: diff --git a/.github/workflows/gitflow-pr-target-check.yml b/.github/workflows/gitflow-pr-target-check.yml index ed800c7..aff8264 100644 --- a/.github/workflows/gitflow-pr-target-check.yml +++ b/.github/workflows/gitflow-pr-target-check.yml @@ -1,3 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 +# © Crown Copyright 2025. This work has been developed by the National Digital Twin Programme and is legally attributed to the Department for Business and Trade (UK) as the governing entity. + name: GitFlow - PR Target Check on: diff --git a/.github/workflows/gitflow-release-checks.yml b/.github/workflows/gitflow-release-checks.yml index c8a3b43..be9460e 100644 --- a/.github/workflows/gitflow-release-checks.yml +++ b/.github/workflows/gitflow-release-checks.yml @@ -1,3 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 +# © Crown Copyright 2025. This work has been developed by the National Digital Twin Programme and is legally attributed to the Department for Business and Trade (UK) as the governing entity. + name: Release Branch Checks on: push: diff --git a/.github/workflows/oss-checker.yml b/.github/workflows/oss-checker.yml new file mode 100644 index 0000000..2bf4025 --- /dev/null +++ b/.github/workflows/oss-checker.yml @@ -0,0 +1,124 @@ +# SPDX-License-Identifier: Apache-2.0 +# © Crown Copyright 2025. This work has been developed by the National Digital Twin Programme and is legally attributed to the Department for Business and Trade (UK) as the governing entity. + +name: Run OSS check helper + +on: + workflow_dispatch: + +jobs: + oss-checks: + runs-on: ubuntu-latest + + steps: + - name: Fetch GitHub App token for target repo + id: target_token + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ secrets.OSPO_WORKFLOW_APP_ID }} + private-key: ${{ secrets.OSPO_WORKFLOW_PRIVATE_KEY }} + permission-contents: read + + - name: Fetch GitHub App token for OSPO source repo (read-only) + id: ospo_token + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ secrets.OSPO_WORKFLOW_APP_ID }} + private-key: ${{ secrets.OSPO_WORKFLOW_PRIVATE_KEY }} + owner: National-Digital-Twin + repositories: ospo-resources + permission-contents: read + + - name: Checkout target repository + uses: actions/checkout@v4 + with: + token: ${{ steps.target_token.outputs.token }} + + - name: Checkout OSPO source repository + uses: actions/checkout@v4 + with: + repository: National-Digital-Twin/ospo-resources + path: ospo-resources + token: ${{ steps.ospo_token.outputs.token }} + + - name: Checkout archetypes source repository + uses: actions/checkout@v4 + with: + repository: National-Digital-Twin/archetypes + path: archetypes + + - name: Test for presence of OSS files and variation from templated content + run: | + missing_files=() + unchanged_files=() + + while IFS= read -r file || [ -n "$file" ]; do + # Skip comments and empty lines + if [[ -z "$file" || "$file" == \#* ]]; then + continue + fi + + target_path="$file" + archetypes_path="archetypes/$file" + + if [ ! -f "$target_path" ]; then + echo "Missing OSS file in target repository: $target_path" + missing_files+=("$file") + elif cmp -s "$target_path" "$archetypes_path"; then + echo "OSS file unchanged from archetypes template: $target_path" + unchanged_files+=("$file") + else + echo "OSS file present and different from the archetypes template: $target_path" + fi + done < ospo-resources/oss-checklist-files.txt + + echo "" + if [ ${#missing_files[@]} -ne 0 ]; then + echo "The following OSS required files are missing:" + printf '%s\n' "${missing_files[@]}" + fi + + if [ ${#unchanged_files[@]} -ne 0 ]; then + echo "The following OSS required files are unchanged from the archetypes template:" + printf '%s\n' "${unchanged_files[@]}" + fi + + if [ ${#missing_files[@]} -ne 0 ] || [ ${#unchanged_files[@]} -ne 0 ]; then + echo "OSS required file check failed." + exit 1 + else + echo "All OSS files are present and have been updated from their original templated content." + fi + + - name: Check GitHub template files are present + run: | + echo "Checking for pull request and issue template files" + + missing_templates=() + + files_to_check=( + ".github/PULL_REQUEST_TEMPLATE.md" + ".github/ISSUE_TEMPLATE/bug_report.md" + ".github/ISSUE_TEMPLATE/feature_request.md" + ) + + for file in "${files_to_check[@]}"; do + if [ ! -f "$file" ]; then + missing_templates+=("$file") + fi + done + + if [ ${#missing_templates[@]} -ne 0 ]; then + echo "" + echo "Required GitHub template files not found:" + printf ' - %s\n' "${missing_templates[@]}" + echo "" + echo "These files help improve project collaboration and are considered best practice." + echo "These need to be included in repository contents to improve the developer and repository consumer experience." + + # Fail the job + echo "Missing required GitHub template files." + exit 1 + else + echo "Required pull request and issue template files present." + fi diff --git a/.github/workflows/publish-github-release.yml b/.github/workflows/publish-github-release.yml new file mode 100644 index 0000000..23a5669 --- /dev/null +++ b/.github/workflows/publish-github-release.yml @@ -0,0 +1,117 @@ +# SPDX-License-Identifier: Apache-2.0 +# © Crown Copyright 2025. This work has been developed by the National Digital Twin Programme and is legally attributed to the Department for Business and Trade (UK) as the governing entity. + +# This workflow is triggered when a pull request is merged into the main branch +# from a release/* branch. It extracts the release version from the source branch, +# generates a Software Bill of Materials (SBOM) using the GitHub API, +# creates a Git tag with the version, and publishes a GitHub release including the SBOM file. + +name: Generate SBOM, Tag and Publish GitHub Release + +on: + pull_request: + types: + - closed + branches: + - main + +permissions: + contents: write + +jobs: + versioning: + if: github.event.pull_request.merged == true && startsWith(github.head_ref, 'release/') + name: Extract Release Version + runs-on: ubuntu-latest + outputs: + version: ${{ steps.extract_version.outputs.VERSION }} + steps: + - name: Extract Version from Source Branch Name + id: extract_version + run: | + SOURCE_BRANCH="${{ github.head_ref }}" + VERSION=$(echo "$SOURCE_BRANCH" | grep -o '[0-9]\+\.[0-9]\+\.[0-9]\+') + + if [ -z "$VERSION" ]; then + echo "Error: No semantic release version found in source branch: $SOURCE_BRANCH" + exit 1 + fi + + echo "VERSION=$VERSION" >> $GITHUB_ENV + echo "VERSION=$VERSION" >> $GITHUB_OUTPUT + + - name: Validate Version Format (Semantic Versioning) + run: | + if [[ ! "${{ env.VERSION }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "Error: Invalid version format found. Expected semantic version in release branch name (e.g., release/0.9.0)" + exit 1 + fi + + - name: Print Tag Version + run: | + echo "Identified release semantic version: ${{ steps.extract_version.outputs.version }}" + + generate-sbom: + name: Generate SPDX SBOM + runs-on: ubuntu-latest + needs: [versioning] + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Generate SPDX SBOM + run: | + # Call GitHub API to generate SBOM + api_response=$(curl -sSL \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + "$GITHUB_API_URL/repos/${{ github.repository }}/dependency-graph/sbom") + + # Extract nested "sbom" object into a valid SPDX file + echo "$api_response" | jq '.sbom' > sbom.spdx.json + + - name: Upload SBOM Artifact + uses: actions/upload-artifact@v4 + with: + name: sbom + path: sbom.spdx.json + + create-git-tag: + name: Create Git Tag + needs: [versioning, generate-sbom] + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Create Git Tag + uses: rickstaa/action-create-tag@v1 + with: + tag: "v${{ needs.versioning.outputs.version }}" + message: "Release v${{ needs.versioning.outputs.version }}" + force_push_tag: true + + create-git-release: + name: Create GitHub Release + needs: [versioning, generate-sbom, create-git-tag] + runs-on: ubuntu-latest + steps: + - name: Download SBOM Artifact + uses: actions/download-artifact@v4 + with: + name: sbom + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + tag_name: "v${{ needs.versioning.outputs.version }}" + name: "Release v${{ needs.versioning.outputs.version }}" + body: "Automated release for version ${{ needs.versioning.outputs.version }}. For details of fixes, new features and changes in this release, please see [CHANGELOG.md](${{ github.server_url }}/${{ github.repository }}/blob/main/CHANGELOG.md)." + draft: false + prerelease: false + files: | + sbom.spdx.json + diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 30f516a..82d2178 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,3 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 +# © Crown Copyright 2025. This work has been developed by the National Digital Twin Programme and is legally attributed to the Department for Business and Trade (UK) as the governing entity. + name: Publish to GHCR on: @@ -59,54 +62,3 @@ jobs: run: | docker push ghcr.io/${{ steps.get-repo.outputs.docker_repo }}:${{ needs.verify.outputs.version }} docker push ghcr.io/${{ steps.get-repo.outputs.docker_repo }}:latest - - tag: - name: Create Git Tag - needs: - - verify - - publish - runs-on: ubuntu-latest - permissions: - contents: write - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Tag commit - run: | - git config --global user.name "${GITHUB_ACTOR}" - git config --global user.email "${GITHUB_ACTOR_ID}+${GITHUB_ACTOR}@users.noreply.github.com" - - TAG=v${{ needs.verify.outputs.version }} - - git tag -a "$TAG" -m "Release $TAG" - git push origin "$TAG" - - release-notes: - name: Create GitHub Release - permissions: - contents: write - needs: - - verify - - tag - runs-on: ubuntu-latest - steps: - - name: Print version - run: | - echo "Creating Release for Version: v${{ needs.verify.outputs.version }}" - - name: Generate Release Notes - run: | - echo "Automated release for version ${{ needs.verify.outputs.version }}. " > ${{ runner.temp }}/release-notes.txt - echo "" >> ${{ runner.temp }}/release-notes.txt - echo "See the [changelog](https://github.com/$GITHUB_REPOSITORY/blob/v${{ needs.verify.outputs.version }}/CHANGELOG.md) for what has changed." >> ${{ runner.temp }}/release-notes.txt - - name: Create Github Release - uses: softprops/action-gh-release@v2 - with: - tag_name: "v${{ needs.verify.outputs.version }}" - name: "Release v${{ needs.verify.outputs.version }}" - body_path: ${{ runner.temp }}/release-notes.txt - draft: false - prerelease: false - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/ACKNOWLEDGMENTS.md b/ACKNOWLEDGEMENTS.md similarity index 100% rename from ACKNOWLEDGMENTS.md rename to ACKNOWLEDGEMENTS.md diff --git a/README.md b/README.md index e0e7082..ff6e3d3 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,12 @@ The data extractor process consists of three parts: - A SPAQRL query to the Secure Agent for data - The option of uploading the results to an AWS S3 bucket +## Testing Guide + +### Running Unit Tests + +Navigate to the root of the project and run `mvn test` to run the tests for the repository. + ## Public Funding Acknowledgment This repository has been developed with public funding as part of the National Digital Twin Programme (NDTP), a UK Government initiative. NDTP, alongside its partners, has invested in this work to advance open, secure, and reusable digital twin technologies for any organisation, whether from the public or private sector, irrespective of size. diff --git a/pom.xml b/pom.xml index d58ea3d..f709c3e 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ uk.gov.dbt.ndtp data-extractor - 0.90.3 + 0.90.4-SNAPSHOT