From c9118301a191bee526b7b89445ae9000f956b088 Mon Sep 17 00:00:00 2001 From: Raj-StepSecurity Date: Mon, 26 Oct 2026 11:25:33 +0530 Subject: [PATCH 1/4] feat: onboarding github-action-markdown-cli --- .dockerignore | 2 + .gitattributes | 1 + .github/CODEOWNERS | 1 + .github/dependabot.yml | 22 + .github/workflows/actions_release.yml | 22 + .github/workflows/audit_package.yml | 28 ++ .github/workflows/auto_cherry_pick.yml | 37 ++ .github/workflows/ci.yml | 66 +++ .github/workflows/release.yml | 51 +++ .github/workflows/scorecard.yml | 46 ++ .gitignore | 2 + .markdownlintrc | 7 + .pre-commit-config.yaml | 49 ++ .yamllint | 26 ++ Dockerfile | 8 + LICENSE | 21 + README.md | 39 +- SECURITY.md | 5 + action.yml | 32 ++ entrypoint.sh | 21 + examples/.markdownlintignore | 1 + examples/ignore/example-ignore.md | 11 + examples/rules/custom.js | 26 ++ markdownlint-problem-matcher.json | 16 + package-lock.json | 597 +++++++++++++++++++++++++ package.json | 8 + 26 files changed, 1144 insertions(+), 1 deletion(-) create mode 100644 .dockerignore create mode 100644 .gitattributes create mode 100644 .github/CODEOWNERS create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/actions_release.yml create mode 100644 .github/workflows/audit_package.yml create mode 100644 .github/workflows/auto_cherry_pick.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/release.yml create mode 100644 .github/workflows/scorecard.yml create mode 100644 .gitignore create mode 100644 .markdownlintrc create mode 100644 .pre-commit-config.yaml create mode 100644 .yamllint create mode 100644 Dockerfile create mode 100644 LICENSE create mode 100644 SECURITY.md create mode 100644 action.yml create mode 100755 entrypoint.sh create mode 100644 examples/.markdownlintignore create mode 100644 examples/ignore/example-ignore.md create mode 100644 examples/rules/custom.js create mode 100644 markdownlint-problem-matcher.json create mode 100644 package-lock.json create mode 100644 package.json diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..4eaf9d2 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +!markdownlint-problem-matcher.json +!entrypoint.sh diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..cf96872 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +package-lock.json linguist-generated=true diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..802421a --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @nosborn diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..cc1856b --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,22 @@ +--- +version: 2 + +updates: + - package-ecosystem: docker + directory: / + schedule: + interval: weekly + + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + + - package-ecosystem: npm + directory: / + schedule: + interval: weekly + versioning-strategy: lockfile-only + cooldown: + default-days: 7 + semver-major-days: 28 diff --git a/.github/workflows/actions_release.yml b/.github/workflows/actions_release.yml new file mode 100644 index 0000000..8e484ee --- /dev/null +++ b/.github/workflows/actions_release.yml @@ -0,0 +1,22 @@ +name: Release GitHub Actions + +on: + workflow_dispatch: + inputs: + tag: + description: "Tag for the release" + required: true + +permissions: + contents: read + +jobs: + release: + permissions: + actions: read + id-token: write + contents: write + + uses: step-security/reusable-workflows/.github/workflows/actions_release.yaml@v1 + with: + tag: "${{ github.event.inputs.tag }}" diff --git a/.github/workflows/audit_package.yml b/.github/workflows/audit_package.yml new file mode 100644 index 0000000..2cc740e --- /dev/null +++ b/.github/workflows/audit_package.yml @@ -0,0 +1,28 @@ +name: NPM Audit Fix Run + +on: + workflow_dispatch: + inputs: + force: + description: "Use --force flag for npm audit fix?" + required: true + type: boolean + base_branch: + description: "Specify a base branch" + required: false + default: "main" + schedule: + - cron: "0 0 * * 1" + +jobs: + audit-fix: + uses: step-security/reusable-workflows/.github/workflows/audit_fix.yml@v1 + with: + force: ${{ inputs.force || false }} + base_branch: ${{ inputs.base_branch || 'main' }} + +permissions: + contents: write + pull-requests: write + packages: read + issues: write diff --git a/.github/workflows/auto_cherry_pick.yml b/.github/workflows/auto_cherry_pick.yml new file mode 100644 index 0000000..7fbe915 --- /dev/null +++ b/.github/workflows/auto_cherry_pick.yml @@ -0,0 +1,37 @@ +name: Auto Cherry-Pick from Upstream + +on: + workflow_run: + workflows: [ "Release GitHub Actions" ] + types: + - completed + + workflow_dispatch: + inputs: + base_branch: + description: "Base branch to create the PR against" + required: true + default: "main" + mode: + description: "Run mode: cherry-pick or verify" + required: false + default: "cherry-pick" + + pull_request: + types: [ opened, synchronize, labeled ] + +permissions: + contents: write + pull-requests: write + packages: read + issues: write + +jobs: + cherry-pick: + if: (github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success') || github.event_name == 'workflow_dispatch' || contains(fromJson(toJson(github.event.pull_request.labels)).*.name, 'review-required') + uses: step-security/reusable-workflows/.github/workflows/auto_cherry_pick.yaml@v1 + with: + original-owner: "nosborn" + repo-name: "github-action-markdown-cli" + base_branch: ${{ inputs.base_branch || 'main' }} + mode: ${{ github.event_name == 'pull_request' && 'verify' || inputs.mode || 'cherry-pick' }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..c3c7b4a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,66 @@ +# yamllint disable rule:line-length +--- +name: CI + +on: + pull_request: + branches: + - master + push: + branches: + - master + +permissions: + contents: read + +concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: true + +jobs: + pre-commit: + runs-on: ubuntu-latest + steps: + - name: Clone the repository + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - name: Set up Python + uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 + with: + python-version: 3.x + - name: Perform pre-commit checks + uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1 + env: + SKIP: no-commit-to-branch + + local-test: + needs: pre-commit + runs-on: ubuntu-latest + steps: + - name: Clone the repository + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - name: Test the problem matcher + id: expect-failure + uses: ./ + with: + config_file: .markdownlintrc + files: . + rules: examples/rules/custom.js + continue-on-error: true + - name: Check the result of the problem matcher test + if: ${{ steps.expect-failure.outcome != 'failure' }} + run: | + exit 1 + - name: Test ignore_files + uses: ./ + with: + config_file: .markdownlintrc + files: . + ignore_files: examples/ignore/* + rules: examples/rules/custom.js + - name: Test ignore_path + uses: ./ + with: + config_file: .markdownlintrc + files: . + ignore_path: examples/.markdownlintignore + rules: examples/rules/custom.js diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..4a59f2d --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,51 @@ +# yamllint disable rule:line-length +--- +name: Release + +on: + push: + tags: + - v*.*.* + +permissions: + contents: read + +concurrency: + group: release + cancel-in-progress: true + +jobs: + release: + permissions: + contents: write + runs-on: ubuntu-latest + + steps: + - name: Clone the repository + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + + - name: Check embedded version numbers + run: | + version="$(grep -F "uses: ${GITHUB_REPOSITORY}@" README.md | cut -d@ -f2)" + if [[ ${version} != "${GITHUB_REF_NAME}" ]]; then + line="$(grep -Fn "uses: ${GITHUB_REPOSITORY}@" README.md | cut -d: -f1)" + printf '::error file=README.md,line=%d::version does not match tag\n' "${line}" + rc=1 + fi + if [[ $(jq -r .version package.json) != "${GITHUB_REF_NAME#v}" ]]; then + line="$(grep -Fn '"version":' package.json | cut -d: -f1)" + printf '::error file=package.json,line=%d::version does not match tag\n' "${line}" + rc=1 + fi + exit "${rc:-0}" + + - name: Create the release + run: | + gh release create "${GITHUB_REF_NAME}" --fail-on-no-commits --generate-notes --verify-tag + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Move the major version tag + run: |- + git tag --force --message="Release ${GITHUB_REF_NAME%%.*}" "${GITHUB_REF_NAME%%.*}" "${GITHUB_REF_NAME}^{}" + git push --force origin "${GITHUB_REF_NAME%%.*}" diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml new file mode 100644 index 0000000..3bbb7f1 --- /dev/null +++ b/.github/workflows/scorecard.yml @@ -0,0 +1,46 @@ +# yamllint disable rule:line-length +# +# There are restrictions on this workflow: +# https://github.com/ossf/scorecard-action#workflow-restrictions +--- +name: OpenSSF Scorecard + +on: + schedule: + - cron: 18 2 * * 1 + push: + branches: + - master + branch_protection_rule: {} + +permissions: # no workflow-level write permissions allowed + contents: read + +concurrency: + group: scorecard + cancel-in-progress: true + +jobs: + analysis: + permissions: + actions: read + contents: read + id-token: write + security-events: write + if: github.event.repository.default_branch == github.ref_name || github.event_name == 'pull_request' + runs-on: ubuntu-latest + steps: + - name: Clone the repository + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + with: + persist-credentials: false + - name: Perform analysis + uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3 + with: + publish_results: true + results_file: results.sarif + results_format: sarif + - name: Upload to code scanning + uses: github/codeql-action/upload-sarif@ce729e4d353d580e6cacd6a8cf2921b72e5e310a # v3.29.0 + with: + sarif_file: results.sarif diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7f4b932 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.envrc +node_modules/ diff --git a/.markdownlintrc b/.markdownlintrc new file mode 100644 index 0000000..0b920fb --- /dev/null +++ b/.markdownlintrc @@ -0,0 +1,7 @@ +{ + "default": true, + "MD003": { + "style": "atx" + }, + "MD013": false +} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..bd77c4f --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,49 @@ +--- +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v5.0.0 + hooks: + - id: check-added-large-files + - id: check-case-conflict + - id: check-executables-have-shebangs + - id: check-json + - id: check-merge-conflict + - id: check-shebang-scripts-are-executable + - id: check-symlinks + - id: check-vcs-permalinks + - id: destroyed-symlinks + - id: end-of-file-fixer + exclude: examples/ignore/example-ignore.md + - id: fix-byte-order-marker + - id: forbid-submodules + - id: mixed-line-ending + - id: no-commit-to-branch + - id: pretty-format-json + args: + - --autofix + exclude: package-lock.json + - id: trailing-whitespace + exclude: examples/ignore/example-ignore.md + + - repo: https://github.com/adrienverge/yamllint + rev: v1.37.1 + hooks: + - id: yamllint + args: + - --config-file=.yamllint + - --strict + + - repo: https://github.com/rhysd/actionlint + rev: v1.7.7 + hooks: + - id: actionlint-docker + + - repo: local + hooks: + - id: package-lock + name: package.json and package-lock.json are in step + entry: npm ci --omit=dev --silent + language: system + pass_filenames: false + +minimum_pre_commit_version: !!str 4.2 diff --git a/.yamllint b/.yamllint new file mode 100644 index 0000000..dd5d9f4 --- /dev/null +++ b/.yamllint @@ -0,0 +1,26 @@ +--- +extends: default + +rules: + braces: + min-spaces-inside-empty: 0 + max-spaces-inside-empty: 0 + brackets: + min-spaces-inside-empty: 0 + max-spaces-inside-empty: 0 + comments: + min-spaces-from-content: 1 # agree with Prettier + document-end: + present: false + indentation: + spaces: 2 + line-length: + allow-non-breakable-words: true + allow-non-breakable-inline-mappings: true + new-lines: + type: unix + quoted-strings: + quote-type: double + required: only-when-needed + truthy: + check-keys: false diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..fc59905 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,8 @@ +FROM node:lts-alpine@sha256:7e0bd0460b26eb3854ea5b99b887a6a14d665d14cae694b78ae2936d14b2befb + +COPY package.json package-lock.json / +RUN npm ci --omit=dev + +COPY entrypoint.sh /entrypoint.sh +COPY markdownlint-problem-matcher.json /markdownlint-problem-matcher.json +ENTRYPOINT ["/entrypoint.sh"] diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..1d59427 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2026 StepSecurity + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/README.md b/README.md index 3cc1c1e..d42a06d 100644 --- a/README.md +++ b/README.md @@ -1 +1,38 @@ -# github-action-markdown-cli \ No newline at end of file +[![StepSecurity Maintained Action](https://raw.githubusercontent.com/step-security/maintained-actions-assets/main/assets/maintained-action-banner.png)](https://docs.stepsecurity.io/actions/stepsecurity-maintained-actions) + +# github-action-markdown-cli + +A GitHub Action that performs style checking and linting for Markdown/CommonMark files using [markdownlint-cli](https://github.com/igorshubovych/markdownlint-cli). + +[![CI Workflow Status](https://github.com/step-security/github-action-markdown-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/step-security/github-action-markdown-cli/actions/workflows/ci.yml) +[![Release Workflow Status](https://github.com/step-security/github-action-markdown-cli/actions/workflows/release.yml/badge.svg)](https://github.com/step-security/github-action-markdown-cli/actions/workflows/release.yml) +[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/step-security/github-action-markdown-cli/badge)](https://scorecard.dev/viewer/?uri=github.com/step-security/github-action-markdown-cli) + +## Usage + +Basic usage with all options enabled: + +```yaml +- name: markdownlint-cli + uses: step-security/github-action-markdown-cli@v3.5.0 + with: + files: . + config_file: .markdownlint.yaml + dot: true + ignore_files: examples/ignore/* + ignore_path: examples/.markdownlintignore + rules: examples/rules/custom.js +``` + +## Inputs + +- `files` - what to process (files, directories, globs) +- `config_file` (optional) - configuration file (JSON or YAML) +- `dot` (optional) - include files/folders with a dot (for example `.github`) +- `ignore_files` (optional) - files to ignore/exclude (file, directory, glob) +- `ignore_path` (optional) - path to file with ignore pattern(s) +- `rules` (optional) - custom rule files (file, directory, glob, package) + +## License + +The scripts and documentation in this project are released under the [MIT License](./LICENSE). diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..77568b2 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,5 @@ +# Security Policy + +## Reporting a Vulnerability + +Please report security vulnerabilities to security@stepsecurity.io diff --git a/action.yml b/action.yml new file mode 100644 index 0000000..59f2bcc --- /dev/null +++ b/action.yml @@ -0,0 +1,32 @@ +--- +name: markdownlint-cli +author: Nick Osborn +description: Style checker and lint tool for Markdown/CommonMark files. + +inputs: + config_file: + description: configuration file (JSON or YAML) + required: false + dot: + description: include files/folders with a dot (for example `.github`) + required: false + files: + description: files, directories, or globs + required: true + ignore_files: + description: files to ignore/exclude + required: false + ignore_path: + description: path to file with ignore pattern(s) + required: false + rules: + description: custom rule files + required: false + +runs: + using: docker + image: Dockerfile + +branding: + icon: check-circle + color: purple diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 0000000..7e93f25 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +MARKDOWNLINT=markdownlint +MARKDOWNLINT="${MARKDOWNLINT}${INPUT_CONFIG_FILE:+ -c ${INPUT_CONFIG_FILE}}" +MARKDOWNLINT="${MARKDOWNLINT}${INPUT_DOT:+ -d}" +MARKDOWNLINT="${MARKDOWNLINT}${INPUT_IGNORE_FILES:+ -i ${INPUT_IGNORE_FILES}}" +MARKDOWNLINT="${MARKDOWNLINT}${INPUT_IGNORE_PATH:+ -p ${INPUT_IGNORE_PATH}}" +MARKDOWNLINT="${MARKDOWNLINT}${INPUT_RULES:+ -r ${INPUT_RULES}}" + +PROBLEM_MATCHER="$(mktemp -p "${GITHUB_WORKSPACE:?}")" +trap 'rm -f "${PROBLEM_MATCHER}"' EXIT +cp /markdownlint-problem-matcher.json "${PROBLEM_MATCHER:?}" || exit +echo "::add-matcher::${PROBLEM_MATCHER:?}" + +# shellcheck disable=SC2086 +npx ${MARKDOWNLINT} ${INPUT_FILES:?} +readonly RC=$? + +echo '::remove-matcher owner=markdownlint::' + +exit "${RC}" diff --git a/examples/.markdownlintignore b/examples/.markdownlintignore new file mode 100644 index 0000000..86f2f93 --- /dev/null +++ b/examples/.markdownlintignore @@ -0,0 +1 @@ +examples/ignore/* diff --git a/examples/ignore/example-ignore.md b/examples/ignore/example-ignore.md new file mode 100644 index 0000000..59a5a43 --- /dev/null +++ b/examples/ignore/example-ignore.md @@ -0,0 +1,11 @@ +# About + +This file should be ingored. + +It has some markdownlint errors on purpose. + +# Additional topic + +Extra space at the end of this line. + +This line is too long for default setup so we just do not know what to write here. diff --git a/examples/rules/custom.js b/examples/rules/custom.js new file mode 100644 index 0000000..fbe564c --- /dev/null +++ b/examples/rules/custom.js @@ -0,0 +1,26 @@ +// this is copy simple rule +// https://github.com/DavidAnson/markdownlint/blob/master/doc/CustomRules.md +// @ts-check + +"use strict"; + +const { URL } = require("url"); + +module.exports = { + "names": [ "any-blockquote" ], + "description": "Rule that reports an error for any blockquote", + "information": new URL("https://example.com/rules/any-blockquote"), + "tags": [ "test" ], + "function": function rule(params, onError) { + params.tokens.filter(function filterToken(token) { + return token.type === "blockquote_open"; + }).forEach(function forToken(blockquote) { + var lines = blockquote.map[1] - blockquote.map[0]; + onError({ + "lineNumber": blockquote.lineNumber, + "detail": "Blockquote spans " + lines + " line(s).", + "context": blockquote.line.substr(0, 7) + }); + }); + } +}; diff --git a/markdownlint-problem-matcher.json b/markdownlint-problem-matcher.json new file mode 100644 index 0000000..22ecf68 --- /dev/null +++ b/markdownlint-problem-matcher.json @@ -0,0 +1,16 @@ +{ + "problemMatcher": [ + { + "owner": "markdownlint", + "pattern": [ + { + "code": 3, + "file": 1, + "line": 2, + "message": 4, + "regexp": "^(.+):(\\d+)(?:\\d+)? (\\S+) (.+)$" + } + ] + } + ] +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..507610f --- /dev/null +++ b/package-lock.json @@ -0,0 +1,597 @@ +{ + "name": "github-action-markdown-cli", + "version": "3.5.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "github-action-markdown-cli", + "version": "3.5.0", + "dependencies": { + "markdownlint-cli": "0.43.0" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/ansi-regex": { + "version": "6.1.0", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.1", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "license": "Python-2.0" + }, + "node_modules/balanced-match": { + "version": "3.0.1", + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, + "node_modules/brace-expansion": { + "version": "4.0.1", + "license": "MIT", + "dependencies": { + "balanced-match": "^3.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "license": "MIT" + }, + "node_modules/commander": { + "version": "12.1.0", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "license": "MIT" + }, + "node_modules/entities": { + "version": "4.5.0", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob": { + "version": "11.0.2", + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^4.0.1", + "minimatch": "^10.0.0", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ignore": { + "version": "6.0.2", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/ini": { + "version": "4.1.3", + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "license": "ISC" + }, + "node_modules/jackspeak": { + "version": "4.1.1", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsonc-parser": { + "version": "3.3.1", + "license": "MIT" + }, + "node_modules/jsonpointer": { + "version": "5.0.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/linkify-it": { + "version": "5.0.0", + "license": "MIT", + "dependencies": { + "uc.micro": "^2.0.0" + } + }, + "node_modules/lru-cache": { + "version": "11.1.0", + "license": "ISC", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/markdown-it": { + "version": "14.1.0", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/markdownlint": { + "version": "0.36.1", + "license": "MIT", + "dependencies": { + "markdown-it": "14.1.0", + "markdownlint-micromark": "0.1.12" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/DavidAnson" + } + }, + "node_modules/markdownlint-cli": { + "version": "0.43.0", + "license": "MIT", + "dependencies": { + "commander": "~12.1.0", + "glob": "~11.0.0", + "ignore": "~6.0.2", + "js-yaml": "^4.1.0", + "jsonc-parser": "~3.3.1", + "jsonpointer": "5.0.1", + "markdownlint": "~0.36.1", + "minimatch": "~10.0.1", + "run-con": "~1.3.2", + "smol-toml": "~1.3.1" + }, + "bin": { + "markdownlint": "markdownlint.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/markdownlint-micromark": { + "version": "0.1.12", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/DavidAnson" + } + }, + "node_modules/mdurl": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/minimatch": { + "version": "10.0.2", + "license": "ISC", + "dependencies": { + "brace-expansion": "^4.0.1" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "license": "BlueOak-1.0.0" + }, + "node_modules/path-key": { + "version": "3.1.1", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "2.0.0", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/punycode.js": { + "version": "2.3.1", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/run-con": { + "version": "1.3.2", + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~4.1.0", + "minimist": "^1.2.8", + "strip-json-comments": "~3.1.1" + }, + "bin": { + "run-con": "cli.js" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/smol-toml": { + "version": "1.3.4", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 18" + }, + "funding": { + "url": "https://github.com/sponsors/cyyynthia" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/uc.micro": { + "version": "2.1.0", + "license": "MIT" + }, + "node_modules/which": { + "version": "2.0.2", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..0c722cd --- /dev/null +++ b/package.json @@ -0,0 +1,8 @@ +{ + "dependencies": { + "markdownlint-cli": "0.43.0" + }, + "name": "github-action-markdown-cli", + "private": true, + "version": "3.5.0" +} From f2d11f7285a59e1ff8ea23607d664d2a9761e23a Mon Sep 17 00:00:00 2001 From: Raj-StepSecurity Date: Mon, 26 Oct 2026 11:28:29 +0530 Subject: [PATCH 2/4] feat: subscription check added and additional changes --- .gitattributes | 1 - .github/CODEOWNERS | 1 - .github/dependabot.yml | 22 ------------- .github/workflows/ci.yml | 12 +++---- .github/workflows/docker.yml | 55 +++++++++++++++++++++++++++++++++ .github/workflows/release.yml | 51 ------------------------------ .github/workflows/scorecard.yml | 46 --------------------------- .npmrc | 1 + .pre-commit-config.yaml | 49 ----------------------------- Dockerfile | 2 ++ LICENSE | 1 + README.md | 2 +- action.yml | 2 +- entrypoint.sh | 41 ++++++++++++++++++++++++ 14 files changed, 108 insertions(+), 178 deletions(-) delete mode 100644 .gitattributes delete mode 100644 .github/CODEOWNERS delete mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/docker.yml delete mode 100644 .github/workflows/release.yml delete mode 100644 .github/workflows/scorecard.yml create mode 100644 .npmrc delete mode 100644 .pre-commit-config.yaml diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index cf96872..0000000 --- a/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -package-lock.json linguist-generated=true diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS deleted file mode 100644 index 802421a..0000000 --- a/.github/CODEOWNERS +++ /dev/null @@ -1 +0,0 @@ -* @nosborn diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index cc1856b..0000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,22 +0,0 @@ ---- -version: 2 - -updates: - - package-ecosystem: docker - directory: / - schedule: - interval: weekly - - - package-ecosystem: github-actions - directory: / - schedule: - interval: weekly - - - package-ecosystem: npm - directory: / - schedule: - interval: weekly - versioning-strategy: lockfile-only - cooldown: - default-days: 7 - semver-major-days: 28 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c3c7b4a..8a2778a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,10 +5,10 @@ name: CI on: pull_request: branches: - - master + - main push: branches: - - master + - main permissions: contents: read @@ -22,13 +22,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Clone the repository - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + uses: actions/checkout@v7 - name: Set up Python - uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 + uses: actions/setup-python@v7 with: python-version: 3.x - name: Perform pre-commit checks - uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1 + uses: step-security/pre-commit-action@v3 env: SKIP: no-commit-to-branch @@ -37,7 +37,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Clone the repository - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + uses: actions/checkout@v7 - name: Test the problem matcher id: expect-failure uses: ./ diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..e07a391 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,55 @@ +name: Publish docker image + +on: + workflow_dispatch: + inputs: + release_tag: + description: 'Tag to release' + required: true + type: string + +permissions: + contents: read + packages: write + +jobs: + build: + runs-on: ubuntu-latest + if: startsWith(github.event.inputs.release_tag, 'v') + steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@v2 + with: + egress-policy: audit + + - name: Checkout + uses: actions/checkout@v7 + - name: Validate tag format + run: | + TAG=${{ github.event.inputs.release_tag }} + if ! echo "$TAG" | grep -Eq '^v[0-9]+\.[0-9]+\.[0-9]+$'; then + echo "❌ Invalid tag format: $TAG" + exit 1 + fi + echo "✅ Valid semver tag: $TAG" + - name: Log in to GitHub Container Registry + uses: step-security/docker-login-action@v4 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Set up QEMU for ARM builds + uses: step-security/setup-qemu-action@v4 + + - name: Set up Docker Buildx + uses: step-security/setup-buildx-action@v4 + + - name: Build and push Docker image + uses: step-security/docker-build-push-action@v7 + with: + context: . + push: true + platforms: linux/amd64,linux/arm64 + tags: | + ghcr.io/${{ github.repository }}:${{ github.event.inputs.release_tag }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 4a59f2d..0000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,51 +0,0 @@ -# yamllint disable rule:line-length ---- -name: Release - -on: - push: - tags: - - v*.*.* - -permissions: - contents: read - -concurrency: - group: release - cancel-in-progress: true - -jobs: - release: - permissions: - contents: write - runs-on: ubuntu-latest - - steps: - - name: Clone the repository - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - - - name: Check embedded version numbers - run: | - version="$(grep -F "uses: ${GITHUB_REPOSITORY}@" README.md | cut -d@ -f2)" - if [[ ${version} != "${GITHUB_REF_NAME}" ]]; then - line="$(grep -Fn "uses: ${GITHUB_REPOSITORY}@" README.md | cut -d: -f1)" - printf '::error file=README.md,line=%d::version does not match tag\n' "${line}" - rc=1 - fi - if [[ $(jq -r .version package.json) != "${GITHUB_REF_NAME#v}" ]]; then - line="$(grep -Fn '"version":' package.json | cut -d: -f1)" - printf '::error file=package.json,line=%d::version does not match tag\n' "${line}" - rc=1 - fi - exit "${rc:-0}" - - - name: Create the release - run: | - gh release create "${GITHUB_REF_NAME}" --fail-on-no-commits --generate-notes --verify-tag - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Move the major version tag - run: |- - git tag --force --message="Release ${GITHUB_REF_NAME%%.*}" "${GITHUB_REF_NAME%%.*}" "${GITHUB_REF_NAME}^{}" - git push --force origin "${GITHUB_REF_NAME%%.*}" diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml deleted file mode 100644 index 3bbb7f1..0000000 --- a/.github/workflows/scorecard.yml +++ /dev/null @@ -1,46 +0,0 @@ -# yamllint disable rule:line-length -# -# There are restrictions on this workflow: -# https://github.com/ossf/scorecard-action#workflow-restrictions ---- -name: OpenSSF Scorecard - -on: - schedule: - - cron: 18 2 * * 1 - push: - branches: - - master - branch_protection_rule: {} - -permissions: # no workflow-level write permissions allowed - contents: read - -concurrency: - group: scorecard - cancel-in-progress: true - -jobs: - analysis: - permissions: - actions: read - contents: read - id-token: write - security-events: write - if: github.event.repository.default_branch == github.ref_name || github.event_name == 'pull_request' - runs-on: ubuntu-latest - steps: - - name: Clone the repository - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - with: - persist-credentials: false - - name: Perform analysis - uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3 - with: - publish_results: true - results_file: results.sarif - results_format: sarif - - name: Upload to code scanning - uses: github/codeql-action/upload-sarif@ce729e4d353d580e6cacd6a8cf2921b72e5e310a # v3.29.0 - with: - sarif_file: results.sarif diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..ec9e05d --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +min-release-age=3 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml deleted file mode 100644 index bd77c4f..0000000 --- a/.pre-commit-config.yaml +++ /dev/null @@ -1,49 +0,0 @@ ---- -repos: - - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v5.0.0 - hooks: - - id: check-added-large-files - - id: check-case-conflict - - id: check-executables-have-shebangs - - id: check-json - - id: check-merge-conflict - - id: check-shebang-scripts-are-executable - - id: check-symlinks - - id: check-vcs-permalinks - - id: destroyed-symlinks - - id: end-of-file-fixer - exclude: examples/ignore/example-ignore.md - - id: fix-byte-order-marker - - id: forbid-submodules - - id: mixed-line-ending - - id: no-commit-to-branch - - id: pretty-format-json - args: - - --autofix - exclude: package-lock.json - - id: trailing-whitespace - exclude: examples/ignore/example-ignore.md - - - repo: https://github.com/adrienverge/yamllint - rev: v1.37.1 - hooks: - - id: yamllint - args: - - --config-file=.yamllint - - --strict - - - repo: https://github.com/rhysd/actionlint - rev: v1.7.7 - hooks: - - id: actionlint-docker - - - repo: local - hooks: - - id: package-lock - name: package.json and package-lock.json are in step - entry: npm ci --omit=dev --silent - language: system - pass_filenames: false - -minimum_pre_commit_version: !!str 4.2 diff --git a/Dockerfile b/Dockerfile index fc59905..f42fa76 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,7 @@ FROM node:lts-alpine@sha256:7e0bd0460b26eb3854ea5b99b887a6a14d665d14cae694b78ae2936d14b2befb +RUN apk add --no-cache jq + COPY package.json package-lock.json / RUN npm ci --omit=dev diff --git a/LICENSE b/LICENSE index 1d59427..5cb1712 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,6 @@ The MIT License (MIT) +Copyright (c) 2019-2025 Nick Osborn Copyright (c) 2026 StepSecurity Permission is hereby granted, free of charge, to any person obtaining a copy diff --git a/README.md b/README.md index d42a06d..afc4a29 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Basic usage with all options enabled: ```yaml - name: markdownlint-cli - uses: step-security/github-action-markdown-cli@v3.5.0 + uses: step-security/github-action-markdown-cli@v3 with: files: . config_file: .markdownlint.yaml diff --git a/action.yml b/action.yml index 59f2bcc..b70af4e 100644 --- a/action.yml +++ b/action.yml @@ -1,6 +1,6 @@ --- name: markdownlint-cli -author: Nick Osborn +author: 'step-security' description: Style checker and lint tool for Markdown/CommonMark files. inputs: diff --git a/entrypoint.sh b/entrypoint.sh index 7e93f25..41db633 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,5 +1,46 @@ #!/bin/sh +# validate subscription status +REPO_PRIVATE=$(jq -r '.repository.private | tostring' "$GITHUB_EVENT_PATH" 2>/dev/null || echo "") +UPSTREAM="nosborn/github-action-markdown-cli" +ACTION_REPO="${GITHUB_ACTION_REPOSITORY:-}" +DOCS_URL="https://docs.stepsecurity.io/actions/stepsecurity-maintained-actions" + +echo "" +echo -e "\033[1;36mStepSecurity Maintained Action\033[0m" +echo "Secure drop-in replacement for $UPSTREAM" +if [ "$REPO_PRIVATE" = "false" ]; then + echo -e "\033[32m✓ Free for public repositories\033[0m" +fi +echo -e "\033[36mLearn more:\033[0m $DOCS_URL" +echo "" + +if [ "$REPO_PRIVATE" != "false" ]; then + SERVER_URL="${GITHUB_SERVER_URL:-https://github.com}" + + if [ "$SERVER_URL" != "https://github.com" ]; then + BODY=$(printf '{"action":"%s","ghes_server":"%s"}' "$ACTION_REPO" "$SERVER_URL") + else + BODY=$(printf '{"action":"%s"}' "$ACTION_REPO") + fi + + API_URL="https://agent.api.stepsecurity.io/v1/github/$GITHUB_REPOSITORY/actions/maintained-actions-subscription" + + RESPONSE=$(curl --max-time 3 -s -w "%{http_code}" \ + -X POST \ + -H "Content-Type: application/json" \ + -d "$BODY" \ + "$API_URL" -o /dev/null) && CURL_EXIT_CODE=0 || CURL_EXIT_CODE=$? + + if [ $CURL_EXIT_CODE -ne 0 ]; then + echo "Timeout or API not reachable. Continuing to next step." + elif [ "$RESPONSE" = "403" ]; then + echo -e "::error::\033[1;31mThis action requires a StepSecurity subscription for private repositories.\033[0m" + echo -e "::error::\033[31mLearn how to enable a subscription: $DOCS_URL\033[0m" + exit 1 + fi +fi + MARKDOWNLINT=markdownlint MARKDOWNLINT="${MARKDOWNLINT}${INPUT_CONFIG_FILE:+ -c ${INPUT_CONFIG_FILE}}" MARKDOWNLINT="${MARKDOWNLINT}${INPUT_DOT:+ -d}" From a557455d60d553819cc156c8e3ee9f7a54641ea3 Mon Sep 17 00:00:00 2001 From: Raj-StepSecurity Date: Mon, 26 Oct 2026 11:32:33 +0530 Subject: [PATCH 3/4] pre commit added pre commit added pre commit added ai analysis addressed --- .pre-commit-config.yaml | 10 ++++++++++ README.md | 6 ++---- SECURITY.md | 2 +- entrypoint.sh | 25 ++++++++++++++++++------- examples/ignore/example-ignore.md | 2 +- 5 files changed, 32 insertions(+), 13 deletions(-) create mode 100644 .pre-commit-config.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..c99b848 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,10 @@ +repos: +- repo: https://github.com/gitleaks/gitleaks + rev: v8.30.1 + hooks: + - id: gitleaks +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v6.0.0 + hooks: + - id: end-of-file-fixer + - id: trailing-whitespace diff --git a/README.md b/README.md index afc4a29..01cd96e 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,10 @@ -[![StepSecurity Maintained Action](https://raw.githubusercontent.com/step-security/maintained-actions-assets/main/assets/maintained-action-banner.png)](https://docs.stepsecurity.io/actions/stepsecurity-maintained-actions) - # github-action-markdown-cli +[![StepSecurity Maintained Action](https://raw.githubusercontent.com/step-security/maintained-actions-assets/main/assets/maintained-action-banner.png)](https://docs.stepsecurity.io/actions/stepsecurity-maintained-actions) + A GitHub Action that performs style checking and linting for Markdown/CommonMark files using [markdownlint-cli](https://github.com/igorshubovych/markdownlint-cli). [![CI Workflow Status](https://github.com/step-security/github-action-markdown-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/step-security/github-action-markdown-cli/actions/workflows/ci.yml) -[![Release Workflow Status](https://github.com/step-security/github-action-markdown-cli/actions/workflows/release.yml/badge.svg)](https://github.com/step-security/github-action-markdown-cli/actions/workflows/release.yml) -[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/step-security/github-action-markdown-cli/badge)](https://scorecard.dev/viewer/?uri=github.com/step-security/github-action-markdown-cli) ## Usage diff --git a/SECURITY.md b/SECURITY.md index 77568b2..69c29a3 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,4 +2,4 @@ ## Reporting a Vulnerability -Please report security vulnerabilities to security@stepsecurity.io +Please report security vulnerabilities to [security@stepsecurity.io](mailto:security@stepsecurity.io) diff --git a/entrypoint.sh b/entrypoint.sh index 41db633..5bb5dac 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -41,20 +41,31 @@ if [ "$REPO_PRIVATE" != "false" ]; then fi fi -MARKDOWNLINT=markdownlint -MARKDOWNLINT="${MARKDOWNLINT}${INPUT_CONFIG_FILE:+ -c ${INPUT_CONFIG_FILE}}" -MARKDOWNLINT="${MARKDOWNLINT}${INPUT_DOT:+ -d}" -MARKDOWNLINT="${MARKDOWNLINT}${INPUT_IGNORE_FILES:+ -i ${INPUT_IGNORE_FILES}}" -MARKDOWNLINT="${MARKDOWNLINT}${INPUT_IGNORE_PATH:+ -p ${INPUT_IGNORE_PATH}}" -MARKDOWNLINT="${MARKDOWNLINT}${INPUT_RULES:+ -r ${INPUT_RULES}}" +set -- markdownlint +if [ -n "${INPUT_CONFIG_FILE}" ]; then + set -- "$@" -c "${INPUT_CONFIG_FILE}" +fi +if [ -n "${INPUT_DOT}" ]; then + set -- "$@" -d +fi +if [ -n "${INPUT_IGNORE_FILES}" ]; then + set -- "$@" -i "${INPUT_IGNORE_FILES}" +fi +if [ -n "${INPUT_IGNORE_PATH}" ]; then + set -- "$@" -p "${INPUT_IGNORE_PATH}" +fi +if [ -n "${INPUT_RULES}" ]; then + set -- "$@" -r "${INPUT_RULES}" +fi PROBLEM_MATCHER="$(mktemp -p "${GITHUB_WORKSPACE:?}")" trap 'rm -f "${PROBLEM_MATCHER}"' EXIT cp /markdownlint-problem-matcher.json "${PROBLEM_MATCHER:?}" || exit echo "::add-matcher::${PROBLEM_MATCHER:?}" +# INPUT_FILES is intentionally word-split to support multiple space-separated paths/globs # shellcheck disable=SC2086 -npx ${MARKDOWNLINT} ${INPUT_FILES:?} +npx "$@" ${INPUT_FILES:?} readonly RC=$? echo '::remove-matcher owner=markdownlint::' diff --git a/examples/ignore/example-ignore.md b/examples/ignore/example-ignore.md index 59a5a43..f9b7adc 100644 --- a/examples/ignore/example-ignore.md +++ b/examples/ignore/example-ignore.md @@ -6,6 +6,6 @@ It has some markdownlint errors on purpose. # Additional topic -Extra space at the end of this line. +Extra space at the end of this line. This line is too long for default setup so we just do not know what to write here. From ff9f8e03dd6c05d29d417258ebd674af5754fd55 Mon Sep 17 00:00:00 2001 From: Raj-StepSecurity Date: Mon, 26 Oct 2026 12:10:29 +0530 Subject: [PATCH 4/4] curl added to dockerfile --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index f42fa76..ee35491 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ FROM node:lts-alpine@sha256:7e0bd0460b26eb3854ea5b99b887a6a14d665d14cae694b78ae2936d14b2befb -RUN apk add --no-cache jq +RUN apk add --no-cache curl jq COPY package.json package-lock.json / RUN npm ci --omit=dev