github.com/yogeshkumararora/slsa-github-generator@v1.10.1-0.20240520161934-11278bd5afb4/Makefile (about)

     1  # Copyright 2023 SLSA Authors
     2  #
     3  # Licensed under the Apache License, Version 2.0 (the "License");
     4  # you may not use this file except in compliance with the License.
     5  # You may obtain a copy of the License at
     6  #
     7  #      http://www.apache.org/licenses/LICENSE-2.0
     8  #
     9  # Unless required by applicable law or agreed to in writing, software
    10  # distributed under the License is distributed on an "AS IS" BASIS,
    11  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  # See the License for the specific language governing permissions and
    13  # limitations under the License.
    14  
    15  SHELL := /bin/bash
    16  OUTPUT_FORMAT ?= $(shell if [ "${GITHUB_ACTIONS}" == "true" ]; then echo "github"; else echo ""; fi)
    17  
    18  .PHONY: help
    19  help: ## Shows all targets and help from the Makefile (this message).
    20  	@echo "slsa-github-generator Makefile"
    21  	@echo "Usage: make [COMMAND]"
    22  	@echo ""
    23  	@grep --no-filename -E '^([/a-z.A-Z0-9_%-]+:.*?|)##' $(MAKEFILE_LIST) | \
    24  		awk 'BEGIN {FS = "(:.*?|)## ?"}; { \
    25  			if (length($$1) > 0) { \
    26  				printf "  \033[36m%-20s\033[0m %s\n", $$1, $$2; \
    27  			} else { \
    28  				if (length($$2) > 0) { \
    29  					printf "%s\n", $$2; \
    30  				} \
    31  			} \
    32  		}'
    33  
    34  node_modules/.installed: package.json package-lock.json
    35  	npm ci
    36  	touch node_modules/.installed
    37  
    38  ## Testing
    39  #####################################################################
    40  
    41  .PHONY: unit-test
    42  unit-test: go-test ts-test ## Runs all unit tests.
    43  
    44  .PHONY: go-test
    45  go-test: ## Run Go unit tests.
    46  	@ # NOTE: go test builds packages even if there are no tests.
    47  	@set -e;\
    48  		go mod vendor; \
    49  		extraargs=""; \
    50  		if [ "$(OUTPUT_FORMAT)" == "github" ]; then \
    51  			extraargs="-v"; \
    52  		fi; \
    53  		go test -mod=vendor $$extraeargs ./...
    54  
    55  .PHONY: ts-test
    56  ts-test: ## Run TypeScript tests.
    57  	@# Run unit tests for all TS actions where tests are found.
    58  	@set -e;\
    59  		PATHS=$$(find .github/actions/ actions/ -not -path '*/node_modules/*' -name __tests__ -type d | xargs dirname); \
    60  		for path in $$PATHS; do \
    61  			make -C $$path unit-test; \
    62  		done
    63  
    64  ## Tools
    65  #####################################################################
    66  
    67  .PHONY: format
    68  format: yaml-format md-format ts-format go-format ## Runs all code formatters.
    69  
    70  .PHONY: yaml-format
    71  yaml-format: node_modules/.installed ## Runs code formatter for YAML files.
    72  	@set -e;\
    73  		yml_files=$$( \
    74  			find . -type f \
    75  				\( \
    76  					-name '*.yml' -o \
    77  					-name '*.yaml' \
    78  				\) \
    79  				-not -iwholename '*/.git/*' \
    80  				-not -iwholename '*/vendor/*' \
    81  				-not -iwholename '*/node_modules/*' \
    82  		); \
    83  		for path in $$yml_files; do \
    84  			./node_modules/.bin/prettier --write $$path; \
    85  		done;
    86  
    87  .PHONY: md-format
    88  md-format: node_modules/.installed ## Runs code formatter for Markdown files.
    89  	@set -e;\
    90  		md_files=$$( \
    91  			find . -type f -name '*.md' \
    92  				-not -iwholename '*/.git/*' \
    93  				-not -iwholename '*/vendor/*' \
    94  				-not -iwholename '*/node_modules/*' \
    95  		); \
    96  		for path in $$md_files; do \
    97  			./node_modules/.bin/prettier --write $$path; \
    98  		done;
    99  
   100  .PHONY: ts-format
   101  ts-format: ## Runs code formatter for TypeScript files.
   102  	@set -e;\
   103  		actions_paths=$$(find .github/actions/ actions/ -not -path '*/node_modules/*' -name package.json -type f | xargs dirname); \
   104  		for path in $$actions_paths; do \
   105  			make -C $$path format; \
   106  		done
   107  
   108  .PHONY: go-format
   109  go-format: ## Runs code formatter for Go files.
   110  	@set -e;\
   111  		go_files=$$( \
   112  			find . -type f -name '*.go' \
   113  				-not -iwholename '*/.git/*' \
   114  				-not -iwholename '*/vendor/*' \
   115  				-not -iwholename '*/node_modules/*' \
   116  		); \
   117  		for path in $$go_files; do \
   118  			gofumpt -w $$path; \
   119  		done;
   120  
   121  COPYRIGHT ?= "SLSA Authors"
   122  LICENSE ?= apache
   123  
   124  .PHONY: autogen
   125  autogen: ## Runs autogen on code files.
   126  	@set -euo pipefail; \
   127  		code_files=$$( \
   128  			find . -type f \
   129  				\( \
   130  					-name '*.go' -o \
   131  					-name '*.ts' -o \
   132  					-name '*.sh' -o \
   133  					-name '*.yaml' -o \
   134  					-name '*.yml' -o \
   135  					-name 'Makefile' \
   136  				\) \
   137  				-not -iwholename '*/.git/*' \
   138  				-not -iwholename '*/vendor/*' \
   139  				-not -iwholename '*/node_modules/*' \
   140  		); \
   141  		for filename in $${code_files}; do \
   142  			if ! ( head "$${filename}" | grep -iL $(COPYRIGHT) > /dev/null ); then \
   143  				echo $${filename}; \
   144  				cd $$(dirname "$${filename}"); \
   145  				autogen -i --no-code --no-tlc -c $(COPYRIGHT) -l $(LICENSE) $$(basename "$${filename}"); \
   146  				cd - > /dev/null; \
   147  			fi; \
   148  		done
   149  
   150  .PHONY: markdown-toc
   151  markdown-toc: node_modules/.installed ## Runs markdown-toc on markdown files.
   152  	@# NOTE: Do not include issue templates since they contain Front Matter.
   153  	@# markdown-toc will update Front Matter even if there is no TOC in the file.
   154  	@# See: https://github.com/jonschlinkert/markdown-toc/issues/151
   155  	@set -euo pipefail; \
   156  		md_files=$$( \
   157  			find . -name '*.md' -type f \
   158  				-not -iwholename '*/.git/*' \
   159  				-not -iwholename '*/vendor/*' \
   160  				-not -iwholename '*/node_modules/*' \
   161  				-not -iwholename '*/.github/ISSUE_TEMPLATE/*' \
   162  		); \
   163  		for filename in $${md_files}; do \
   164  			npm run markdown-toc "$${filename}"; \
   165  		done;
   166  
   167  ## Linters
   168  #####################################################################
   169  
   170  .PHONY: lint
   171  lint: markdownlint golangci-lint shellcheck eslint yamllint actionlint renovate-config-validator ## Run all linters.
   172  
   173  .PHONY: actionlint
   174  actionlint: ## Runs the actionlint linter.
   175  	@# NOTE: We need to ignore config files used in tests.
   176  	@set -e;\
   177  		files=$$( \
   178  			find .github/workflows/ -type f \
   179  				\( \
   180  					-name '*.yaml' -o \
   181  					-name '*.yml' \
   182  				\) \
   183  				-not -iwholename '*/configs-*/*' \
   184  		); \
   185  		if [ "$(OUTPUT_FORMAT)" == "github" ]; then \
   186  			actionlint -format '{{range $$err := .}}::error file={{$$err.Filepath}},line={{$$err.Line}},col={{$$err.Column}}::{{$$err.Message}}%0A```%0A{{replace $$err.Snippet "\\n" "%0A"}}%0A```\n{{end}}' -ignore 'SC2016:' $${files}; \
   187  		else \
   188  			actionlint $${files}; \
   189  		fi
   190  
   191  .PHONY: markdownlint
   192  markdownlint: node_modules/.installed ## Runs the markdownlint linter.
   193  	@set -e;\
   194  		if [ "$(OUTPUT_FORMAT)" == "github" ]; then \
   195  			exit_code=0; \
   196  			while IFS="" read -r p && [ -n "$$p" ]; do \
   197  				file=$$(echo "$$p" | jq -c -r '.fileName // empty'); \
   198  				line=$$(echo "$$p" | jq -c -r '.lineNumber // empty'); \
   199  				endline=$${line}; \
   200  				message=$$(echo "$$p" | jq -c -r '.ruleNames[0] + "/" + .ruleNames[1] + " " + .ruleDescription + " [Detail: \"" + .errorDetail + "\", Context: \"" + .errorContext + "\"]"'); \
   201  				exit_code=1; \
   202  				echo "::error file=$${file},line=$${line},endLine=$${endline}::$${message}"; \
   203  			done <<< "$$(./node_modules/.bin/markdownlint --dot --json . 2>&1 | jq -c '.[]')"; \
   204  			exit "$${exit_code}"; \
   205  		else \
   206  			npm run markdownlint; \
   207  		fi
   208  
   209  .PHONY: golangci-lint
   210  golangci-lint: ## Runs the golangci-lint linter.
   211  	@set -e;\
   212  		extraargs=""; \
   213  		if [ "$(OUTPUT_FORMAT)" == "github" ]; then \
   214  			extraargs="--out-format github-actions"; \
   215  		fi; \
   216  		golangci-lint run -c .golangci.yml ./... $$extraargs
   217  
   218  SHELLCHECK_ARGS = --severity=style --external-sources
   219  
   220  .PHONY: shellcheck
   221  shellcheck: ## Runs the shellcheck linter.
   222  	@set -e;\
   223  		files=$$(find . -type f -not -iwholename '*/.git/*' -not -iwholename '*/vendor/*' -not -iwholename '*/node_modules/*' -exec bash -c 'file "$$1" | cut -d':' -f2 | grep --quiet shell' _ {} \; -print); \
   224  		if [ "$(OUTPUT_FORMAT)" == "github" ]; then \
   225  			exit_code=0; \
   226  			while IFS="" read -r p && [ -n "$$p" ]; do \
   227  				level=$$(echo "$$p" | jq -c '.level // empty' | tr -d '"'); \
   228  				file=$$(echo "$$p" | jq -c '.file // empty' | tr -d '"'); \
   229  				line=$$(echo "$$p" | jq -c '.line // empty' | tr -d '"'); \
   230  				endline=$$(echo "$$p" | jq -c '.endLine // empty' | tr -d '"'); \
   231  				col=$$(echo "$$p" | jq -c '.column // empty' | tr -d '"'); \
   232  				endcol=$$(echo "$$p" | jq -c '.endColumn // empty' | tr -d '"'); \
   233  				message=$$(echo "$$p" | jq -c '.message // empty' | tr -d '"'); \
   234  				exit_code=1; \
   235  				case $$level in \
   236  				"info") \
   237  					echo "::notice file=$${file},line=$${line},endLine=$${endline},col=$${col},endColumn=$${endcol}::$${message}"; \
   238  					;; \
   239  				"warning") \
   240  					echo "::warning file=$${file},line=$${line},endLine=$${endline},col=$${col},endColumn=$${endcol}::$${message}"; \
   241  					;; \
   242  				"error") \
   243  					echo "::error file=$${file},line=$${line},endLine=$${endline},col=$${col},endColumn=$${endcol}::$${message}"; \
   244  					;; \
   245  				esac; \
   246  			done <<< "$$(echo -n "$$files" | xargs shellcheck -f json $(SHELLCHECK_ARGS) | jq -c '.[]')"; \
   247  			exit "$${exit_code}"; \
   248  		else \
   249  			echo -n "$$files" | xargs shellcheck $(SHELLCHECK_ARGS); \
   250  		fi
   251  
   252  .PHONY: eslint
   253  eslint: ## Runs the eslint linter.
   254  	@set -e;\
   255  		PATHS=$$(find .github/actions/ actions/ -not -path '*/node_modules/*' -name package.json -type f | xargs dirname); \
   256  		for path in $$PATHS; do \
   257  			make -C $$path lint; \
   258  		done
   259  
   260  .PHONY: yamllint
   261  yamllint: ## Runs the yamllint linter.
   262  	@set -e;\
   263  		extraargs=""; \
   264  		if [ "$(OUTPUT_FORMAT)" == "github" ]; then \
   265  			extraargs="-f github"; \
   266  		fi; \
   267  		yamllint --strict -c .yamllint.yaml . $$extraargs
   268  
   269  .PHONY: renovate-config-validator
   270  renovate-config-validator: node_modules/.installed ## Runs renovate-config-validator
   271  	@npm run renovate-config-validator
   272  
   273  ## Maintenance
   274  #####################################################################
   275  
   276  .PHONY: clean
   277  clean: ## Delete temporary files.
   278  	rm -rf node_modules