Skip to content

Adding Check and Apply Header workflow files - #319

Open
danielsoden0404 wants to merge 6 commits into
developfrom
feature/copyright-header-workflows
Open

danielsoden0404 wants to merge 6 commits into
developfrom
feature/copyright-header-workflows

Conversation

@danielsoden0404

Copy link
Copy Markdown

Copyright Header Workflows

Check workflow

The check workflow is intended to run on pull requests.

Functionality:

  • Checks the repository for supported source files that do not already contain the expected header
  • Creates the expected header template from the first copyright line in the repository NOTICE file
  • Uses the current repository organisation name extracted from NOTICE
  • Posts a pull request comment listing files that are missing headers
  • Includes the exact header text that will be applied if the apply workflow is run

If all matching files already contain the expected header, the workflow posts a success comment instead.

Apply workflow

The apply workflow will be ran manually with workflow_dispatch after a pull request

Functionality:

  • Creates the same header template used by the check workflow
  • Adds headers to supported files that are missing them
  • Commits the changes as github-actions[bot]
  • Pushes the commit back to the selected branch

Copilot AI lite review requested due to automatic review settings August 10, 2026 09:25
@danielsoden0404
danielsoden0404 requested a review from a team as a code owner August 10, 2026 09:25

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds two GitHub Actions workflows to (1) detect missing copyright/license headers on pull requests and (2) apply the expected header template to matching files via a manual dispatch workflow. This fits into the repo’s automation by standardizing source-file headers based on the NOTICE file content.

Changes:

  • Introduces a PR-facing “check” workflow that builds a header template from NOTICE, runs addlicense -check, and posts/updates a PR comment with results.
  • Introduces a manual “apply” workflow that generates the same template, applies headers with addlicense, and commits/pushes the changes back to the selected branch.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
.github/workflows/check-headers.yml Adds PR check workflow that generates a header template from NOTICE, runs addlicense -check, and comments on the PR with missing-header results and the header preview.
.github/workflows/apply-headers.yml Adds manual workflow that applies the same header template via addlicense, then commits and pushes changes to the branch.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread .github/workflows/apply-headers.yml Outdated
Comment thread .github/workflows/check-headers.yml
Comment thread .github/workflows/check-headers.yml
Comment thread .github/workflows/check-headers.yml Outdated
Copilot AI review requested due to automatic review settings August 10, 2026 09:28

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Suppressed comments (3)

.github/workflows/check-headers.yml:165

  • The comment lookup can return multiple matching IDs; assigning them to COMMENT_ID and using it in a single DELETE call can fail (newline-separated IDs) and can also leave older matching comments behind. Consider deleting all matching bot comments, or at least selecting one deterministically.
          COMMENT_ID=$(gh api "repos/${GITHUB_REPOSITORY}/issues/${GITHUB_PULL_REQUEST_NUMBER}/comments" -q '.[] | select(.user.login=="github-actions[bot]" and (.body | contains("Automated Copyright License Check"))) | .id')

          if [ -z "$COMMENT_ID" ]; then
            echo "Creating new copyright check warning comment"
          else

.github/workflows/apply-headers.yml:101

  • The heredoc content lines are indented, which will be written into /tmp/copyright.tmpl as leading whitespace. That will produce headers with extra spaces at the start of each line when addlicense applies them.
          chmod 0600 /tmp/copyright.tmpl

.github/workflows/check-headers.yml:103

  • The heredoc content lines are indented, which will be written into /tmp/copyright.tmpl as leading whitespace. That will produce headers with extra spaces at the start of each line (e.g., "// Copyright ..."), which can cause header mismatches and looks incorrect when applied to source files.
          chmod 0600 /tmp/copyright.tmpl

Copilot AI review requested due to automatic review settings August 10, 2026 14:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Suppressed comments (2)

.github/workflows/check-headers.yml:162

  • gh api ... -q '.[] | select(...) | .id' can return multiple matching comment IDs (one per line). In that case COMMENT_ID becomes a multiline string and the subsequent DELETE request will fail. Consider selecting a single comment (e.g., the most recent match) or iterating over all matches.
          COMMENT_ID=$(gh api "repos/${GITHUB_REPOSITORY}/issues/${GITHUB_PULL_REQUEST_NUMBER}/comments" -q '.[] | select(.user.login=="github-actions[bot]" and (.body | contains("Automated Copyright License Check"))) | .id')

.github/workflows/check-headers.yml:33

  • The NOTICE parsing + template creation logic is duplicated across check-headers.yml and apply-headers.yml (e.g., compare this step with .github/workflows/apply-headers.yml:27-101). This increases the risk that the check/apply workflows drift and start generating different expected headers. Consider extracting the shared logic into a composite action (or a reusable workflow) and calling it from both workflows.
      - name: Extract organisation from NOTICE file from root
        id: extract_organisation
        run: |
          if [ ! -f NOTICE ]; then
            echo "::error file=NOTICE::NOTICE file is required at the repository root"

Copilot AI review requested due to automatic review settings August 11, 2026 09:00

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Suppressed comments (3)

.github/workflows/check-headers.yml:168

  • COMMENT_ID can contain multiple IDs if there are multiple previous bot comments matching the filter; passing a multi-line value into the DELETE endpoint will fail. Collect all matching IDs and delete them in a loop (or select a single ID explicitly).
          COMMENT_ID=$(gh api "repos/${GITHUB_REPOSITORY}/issues/${GITHUB_PULL_REQUEST_NUMBER}/comments" -q '.[] | select(.user.login=="github-actions[bot]" and (.body | contains("Automated Copyright License Check"))) | .id')

          if [ -z "$COMMENT_ID" ]; then
            echo "Creating new copyright check warning comment"
          else
            echo "Replacing old copyright check warning comment"
            gh api -X DELETE "repos/${GITHUB_REPOSITORY}/issues/comments/${COMMENT_ID}"
          fi

.github/workflows/check-headers.yml:9

  • The PR-comment step uses the Issues Comments REST API endpoints, but the workflow token permissions do not grant issues: write. This is likely to fail with a 403 when creating/deleting the comment; add issues: write (you can keep pull-requests: write if needed elsewhere).
permissions:
  contents: read
  pull-requests: write

.github/workflows/check-headers.yml:44

  • The NOTICE parsing + template creation logic is duplicated across check-headers.yml and apply-headers.yml. This makes future changes to the header format/error handling easy to accidentally apply to only one workflow; consider extracting these steps into a reusable workflow or composite action and calling it from both workflows.
      - name: Extract organisation from NOTICE file from root
        id: extract_organisation
        run: |
          if [ ! -f NOTICE ]; then
            echo "::error file=NOTICE::NOTICE file is required at the repository root"
            exit 1
          fi

          copyright_line=$(grep -im1 'copyright' NOTICE || true)

          if [ -z "$copyright_line" ]; then
            echo "::error file=NOTICE::NOTICE must contain a copyright line"
            exit 1
          fi

          organisation=$(printf '%s\n' "$copyright_line" | sed -E 's/.*[Cc]opyright( \(c\))?[[:space:]]*//; s/^([0-9]{4}([[:space:]]*[-,][[:space:]]*[0-9]{4})*[[:space:]]*)+//; s/[[:space:]]+$//; s/\.$//')

Copilot AI review requested due to automatic review settings August 17, 2026 08:34

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Suppressed comments (4)

.github/workflows/check-headers.yml:161

  • COMMENT_ID is derived from a jq filter that can return multiple comment IDs (and the issues comments API is paginated by default). If more than one matching bot comment exists, or the bot comment is older than the first page of results, this variable can contain multiple IDs or be empty, causing the delete call to fail and duplicate comments to accumulate. Paginate and select a single ID (e.g., the most recent) before deleting.
          COMMENT_ID=$(gh api "repos/${GITHUB_REPOSITORY}/issues/${GITHUB_PULL_REQUEST_NUMBER}/comments" -q '.[] | select(.user.login=="github-actions[bot]" and (.body | contains("Automated Copyright License Check"))) | .id')

.github/workflows/check-headers.yml:150

  • The success message is grammatically off (singular “header” while referring to multiple files).
              echo 'No files missing copyright header.'

.github/workflows/check-headers.yml:127

  • The find command scans ignored directories (node_modules/build/dist/.github) and relies on addlicense -ignore to skip them later. This can significantly increase runtime on large repos; it's more efficient to exclude these paths in find as well.
          if ! find . -not -path './.git/*' -type f \( "${FIND_ARGS[@]}" \) -print0 | \

.github/workflows/apply-headers.yml:129

  • As in the check workflow, find currently scans ignored directories and relies on addlicense -ignore to skip them. Excluding these paths in find can reduce runtime and resource usage.
          find . -not -path './.git/*' -type f \( "${FIND_ARGS[@]}" \) -print0 | \

@danielsoden0404 danielsoden0404 changed the title Action: Experimental check and apply header workflow files Adding Check and Apply Header workflow files Aug 21, 2026
Copilot AI review requested due to automatic review settings August 21, 2026 10:38
@github-actions

Copy link
Copy Markdown

⚠️ Automated Copyright License Check

The following files are missing the copyright header:

./framework/fileStore/VTS_L3/vtsconfig_dsDisplay.py
./framework/fileStore/VTS_L3/vtsconfig_dsHost.py
./framework/fileStore/VTS_L3/vtsconfig_dsVideoPort.py
./framework/fileStore/VTS_L3/vtsconfig_dsAudio.py
./framework/fileStore/VTS_L3/vtsconfig_rmfaudiocapture.py
./framework/fileStore/VTS_L3/vtsconfig_dsVideoDevice.py
./framework/fileStore/VTS_L3/vtsconfig_deepsleep.py
./framework/fileStore/vulkan_report_generator.py
./framework/fileStore/FireCertAppTestVariables.py

To add the copyright header below to the files listed above, select Apply Copyright Headers with Google Addlicense workflow.

If not stated otherwise in this file or this component's LICENSE file the
following copyright and licenses apply:

Copyright 2026 RDK Management

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Suppressed comments (16)

.github/workflows/apply-headers.yml:126

  • addlicense v1.2.0 accepts -ignore as one comma-separated option. Passing the flag four times causes the later value to replace the earlier ones, so only **/.github/** is ignored; files under node_modules, build, and dist can then be checked or modified. Pass IGNORE_PATTERN as a single -ignore argument (or use the tool's supported pattern syntax).
          IFS=',' read -r -a IGNORE_ARRAY <<< "$IGNORE_PATTERN"
          IGNORE_FLAGS=()
          for pattern in "${IGNORE_ARRAY[@]}"; do
            IGNORE_FLAGS+=("-ignore" "$pattern")
          done

.github/workflows/apply-headers.yml:106

  • The repository contains HTML source files with these headers (for example, framework/fileStore/lightning-apps/htmlplayer.html), but *.html is absent from the include list. A new or modified HTML file without a header will therefore be skipped by the apply workflow, so it will not add headers to all supported source files.
          INCLUDE_PATTERN: "**/*.c,**/*.cc,**/*.cpp,**/*.cxx,**/*.h,**/*.hh,**/*.hpp,**/*.hxx,**/*.go,**/*.sh,**/*.bash,**/*.py,**/*.java,**/*.js,**/*.ts"

.github/workflows/apply-headers.yml:142

  • workflow_dispatch can be run against a tag as well as a branch, but this refspec always treats GITHUB_REF_NAME as a branch destination. Running the workflow on a tag can create or update an unintended branch, or fail, instead of pushing the selected ref. Restrict the workflow to branch refs before committing and pushing.
          git push origin "HEAD:${GITHUB_REF_NAME}"

.github/workflows/apply-headers.yml:142

  • This push uses the checkout's GITHUB_TOKEN, so GitHub suppresses downstream workflow runs caused by the push. The pull_request check therefore will not rerun after headers are applied, leaving the prior missing-header comment stale even though the branch is now fixed. Trigger an explicit check with pull-request context or update/replace the comment from the apply workflow.
          git push origin "HEAD:${GITHUB_REF_NAME}"

.github/workflows/apply-headers.yml:85

  • The template contains a literal space before {{.Year}} inside the conditional, in addition to the space before {{ if ... }}. Go templates preserve both spaces, so addlicense will write Copyright 2026 RDK Management instead of the repository's single-space header. Move the conditional's space after the year.
          Copyright {{ if .Year }} {{.Year}}{{ end }} ${ORGANISATION}

.github/workflows/apply-headers.yml:64

  • The Comcast template has the same whitespace issue: the space inside {{ if .Year }} is preserved in addition to the preceding literal space, so addlicense writes two spaces between Copyright and the year. Move the conditional's space after the year.
          Copyright {{ if .Year }} {{.Year}}{{ end }} ${ORGANISATION}

.github/workflows/check-headers.yml:124

  • addlicense v1.2.0 accepts -ignore as one comma-separated option. Passing the flag four times causes the later value to replace the earlier ones, so only **/.github/** is ignored; files under node_modules, build, and dist can then be checked or modified. Pass IGNORE_PATTERN as a single -ignore argument (or use the tool's supported pattern syntax).
          IFS=',' read -r -a IGNORE_ARRAY <<< "$IGNORE_PATTERN"
          IGNORE_FLAGS=()
          for pattern in "${IGNORE_ARRAY[@]}"; do
            IGNORE_FLAGS+=("-ignore" "$pattern")
          done

.github/workflows/check-headers.yml:85

  • The generic template says this component's LICENSE file, but the repository's existing headers consistently use this component's Licenses.txt (for example, framework/fileStore/lightning-apps/htmlplayer.html:2 and utilities/TDK_Automation_Scripts/python-lib/resetAgent.py:3). Because this is the template passed to addlicense -check, existing files will be reported as missing and the apply workflow can prepend a second header instead of recognizing them. Match the existing header wording, or migrate the existing headers before enabling this check.
          If not stated otherwise in this file or this component's LICENSE file the
          following copyright and licenses apply:

.github/workflows/check-headers.yml:109

  • The repository contains HTML source files with these headers (for example, framework/fileStore/lightning-apps/htmlplayer.html), but *.html is absent from the include list. A new or modified HTML file without a header will therefore be skipped by the check workflow, so the advertised coverage is incomplete.
          INCLUDE_PATTERN: "**/*.c,**/*.cc,**/*.cpp,**/*.cxx,**/*.h,**/*.hh,**/*.hpp,**/*.hxx,**/*.go,**/*.sh,**/*.bash,**/*.py,**/*.java,**/*.js,**/*.ts"

.github/workflows/check-headers.yml:127

  • Any nonzero status from this pipeline is interpreted as "files missing headers." That also covers find, xargs, and addlicense execution errors such as unreadable input or a malformed template; the script then writes a misleading missing-header comment and exits successfully. Capture operational failures separately and only build the missing-file report for the expected addlicense check result.
          if ! find . -not -path './.git/*' -type f \( "${FIND_ARGS[@]}" \) -print0 | \
            xargs -0 -r addlicense -f /tmp/copyright.tmpl "${IGNORE_FLAGS[@]}" -check > /tmp/addlicense_output.txt 2>&1; then

.github/workflows/check-headers.yml:161

  • This lookup reads only the first API page and emits every matching comment ID. Once a pull request has more than the default page size, the old bot comment is not found and another is created; if duplicate comments exist from concurrent runs, the newline-separated IDs make the single DELETE URL invalid. Paginate the lookup and delete or replace matching IDs individually (or select one deterministically).
          COMMENT_ID=$(gh api "repos/${GITHUB_REPOSITORY}/issues/${GITHUB_PULL_REQUEST_NUMBER}/comments" -q '.[] | select(.user.login=="github-actions[bot]" and (.body | contains("Automated Copyright License Check"))) | .id')

.github/workflows/check-headers.yml:143

  • The preview substitutes the year when the check runs, while the apply workflow leaves .Year for addlicense to resolve when the manual workflow runs. A dispatch after a calendar-year rollover therefore commits a different header from the one shown in the pull request comment, so the preview is not exact. Persist or pass a fixed year to both workflows, or regenerate the preview from the value used by apply.
              sed "s/{{ if \.Year }} {{\.Year}}{{ end }}/${current_year}/" /tmp/copyright.tmpl

.github/workflows/check-headers.yml:66

  • The Comcast template has the same whitespace issue: the space inside {{ if .Year }} is preserved in addition to the preceding literal space, producing two spaces between Copyright and the year. This also makes the header written by addlicense differ from the one shown by the check workflow. Move the conditional's space after the year and update the check workflow's replacement expression too.
          Copyright {{ if .Year }} {{.Year}}{{ end }} ${ORGANISATION}

.github/workflows/check-headers.yml:87

  • The template contains a literal space before {{.Year}} inside the conditional, in addition to the space before {{ if ... }}. Go templates preserve both spaces, so addlicense will render Copyright 2026 RDK Management, while the sed output in this workflow and the repository's existing headers use a single space. Move the conditional's space after the year and update the replacement expression below so the applied and displayed headers remain identical.
          Copyright {{ if .Year }} {{.Year}}{{ end }} ${ORGANISATION}

.github/workflows/apply-headers.yml:83

  • The generic template says this component's LICENSE file, but the repository's existing headers consistently use this component's Licenses.txt (for example, framework/fileStore/lightning-apps/htmlplayer.html:2 and utilities/TDK_Automation_Scripts/python-lib/resetAgent.py:3). Because this is the template passed to addlicense, existing files will not match the header this workflow is intended to apply, so the apply run can prepend a second header. Match the existing header wording, or migrate the existing headers before enabling this workflow.

This issue also appears on line 122 of the same file.

          If not stated otherwise in this file or this component's LICENSE file the
          following copyright and licenses apply:

.github/workflows/check-headers.yml:9

  • For a fork-originated pull_request, GitHub normally downgrades GITHUB_TOKEN permissions to read-only, so the final gh pr comment call cannot create or delete comments even though pull-requests: write is declared here. The check therefore fails for ordinary fork PRs; use a trusted comment job that does not execute pull-request code (or otherwise handle fork events without requiring write access).

This issue also appears in the following locations of the same file:

  • line 84
  • line 120
permissions:
  contents: read
  pull-requests: write

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants