diff --git a/.github/workflows/generate-report.yml b/.github/workflows/generate-report.yml new file mode 100644 index 000000000..45e1e0afc --- /dev/null +++ b/.github/workflows/generate-report.yml @@ -0,0 +1,77 @@ +name: Generate Tests Report + +on: + workflow_dispatch: + + push: + branches: + - main + - "release-[0-9].[0-9][0-9]" + +jobs: + build: + runs-on: ubuntu-latest + env: + SHELL: /bin/bash + XDG_CACHE_HOME: ${{ github.workspace }}/cache + + steps: + - name: Set up Go 1.23 + uses: actions/setup-go@v5 + with: + go-version: 1.23.6 + + # Since we only use the checked out repo for the report generation code, + # always grab the latest from the default branch rather than the branch + # that triggered this action. + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.repository.default_branch }} + + - name: Install ginkgo + run: make install-ginkgo + + # Actions cache is immutable, so to prevent generating a new cache every + # run when we only care about the latest cache, use an artifact instead + # and just overwrite every run. + - name: Restore report cache + continue-on-error: true + uses: actions/download-artifact@v4 + with: + name: report-cache + path: ${{ env.XDG_CACHE_HOME }}/eco-gotests + + - name: Generate report + run: go run ./internal/report -v 100 -b 'main release-*' -o ./report -a "${ACTION_URL}" + env: + ACTION_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + + - name: Upload generated report as artifact + id: upload-pages + uses: actions/upload-pages-artifact@v3 + with: + path: ./report + + - name: Save report cache + uses: actions/upload-artifact@v4 + with: + name: report-cache + overwrite: true + path: ${{ env.XDG_CACHE_HOME }}/eco-gotests + + deploy: + needs: build + + permissions: + pages: write + id-token: write + + environment: + name: github-pages + url: ${{ steps.upload-pages.outputs.page_url }} + + runs-on: ubuntu-latest + steps: + - name: Deploy to GitHub pages + id: upload-pages + uses: actions/deploy-pages@v4 diff --git a/internal/report/README.md b/internal/report/README.md new file mode 100644 index 000000000..9971de32c --- /dev/null +++ b/internal/report/README.md @@ -0,0 +1,80 @@ +# ginkgo report generator + +Generate HTML reports for the tree of Ginkgo specs. [Available on GitHub pages.] + +[Available on GitHub pages.]: https://openshift-kni.github.io/eco-gotests/report + +## Usage + +``` +go run ./internal/report [flags] +``` + +Documentation may be viewed using the following command: + +``` +go doc ./internal/report +``` + +### Examples + +For viewing the tree for a single branch while printing all logs: + +``` +go run ./internal/report -v 100 -b +``` + +For viewing the trees for all branches without printing any logs: + +``` +go run ./internal/report -b 'main release-*' +``` + +For viewing the trees and generating an html report: + +``` +go run ./internal/report -b main -o +``` + +## Developing + +### Architecture + +Although this consists entirely of a single Go package, it generally treats each file as its own package when it comes to exported vs unexported values. Unexported values are generally meant to be used in the file they are defined whereas exported values are meant for reuse by other files. + +For this purpose, the program is split into the following files: + +* `cache.go`: Contains the Cache type and manages the cache directory. This allows the program to only do a Ginkgo dry run when either the program source or the branch is updated. +* `command.go`: Wrapper around local commands, such as various git and ginkgo commands. +* `main.go`: Entrypoint for the program that has the doc comment, handles command line flags, and orchestrates report caching and generation. +* `sum.go`: Generates a SHA-256 sum of the program source code used for validating cache. This guarantees that invalid cache formats will not be loaded. +* `template.go`: Configs and functions for generating reports based on `report_template.html` and `tree_template.html`. +* `tree.go`: Defines the SuiteTree type representing the tree of specs in `tests/`. +* `report_template.html`: Template for the main page of a report listing the branches and revisions included therein. +* `tree_template.html`: Template for a single branch that contains a tree of all the specs. + +### Program flow + +1. Flags are parsed. +1. If help flag specified, help is printed and program exits. +1. If clean flag specified, cache is cleaned and program exits. +1. Trees are generated based on the branch flag. + 1. If branch flag nonempty, attempt to get trees for all branches matching the patterns. Trees not present in the cache get cloned and have a dry run performed. + 1. If branch flag empty, attempt to get trees from the repo in the current directory. Cache is checked for the current directory and a clone and dry run is performed if necessary. + 1. Once updated, the cache is saved before any processing of the trees. + 1. Trees are trimmed and sorted to clean them up for displaying. +1. Trees are printed to stdout. +1. If output flag nonempty, the generated tree map is used to fill in the templates. + +### GitHub workflow + +On push to the main or release branches, the GitHub workflow runs with this flow: + +1. Setup environment, including checking out the default branch and installing go and ginkgo. +1. Attempt to restore cache. +1. Run the program on main and release branches. A report is generated and the current action URL provided. +1. The generated report is uploaded as an artifact in the format necessary for deploying to pages. +1. Attempt to save cache. +1. Deploy the generated pages artifact. + +With this workflow, the entire report is generated on every run, ensuring all branch reports stay up to date with the latest template. A dry run is only performed for the branch that changed or all branches if the source code changes. Since changes to the report program are much rarer than other changes to the branches, the total runtime should be about the same as just the dry run step in the existing Makefile CI.