Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 8 additions & 48 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,114 +16,87 @@ jobs:
defaults:
run:
shell: bash

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"

- name: Cache npm package cache
uses: actions/cache@v4
with:
path: ~/.npm
key: npm-markdown-tools-${{ runner.os }}-markdownlint-cli2-0.22.1-markdown-link-check-3
restore-keys: |
npm-markdown-tools-${{ runner.os }}-

- name: Install validation tools
run: |
set -euo pipefail

python -m pip install --upgrade pip
python -m pip install "PyYAML==6.0.2" "ruff==0.8.6"

sudo apt-get update
sudo apt-get install -y shellcheck

npm install --global markdownlint-cli2@0.22.1 markdown-link-check@3

- name: Validate Python syntax in scripts
run: |
set -euo pipefail

if [[ -d "scripts" ]]; then
python -m compileall scripts
else
echo "No scripts directory found. Skipping Python syntax validation."
fi

- name: Run Python lint with ruff
continue-on-error: true
run: |
set -euo pipefail

if [[ -d "scripts" ]]; then
ruff check scripts --output-format=github
else
echo "No scripts directory found. Skipping ruff."
fi

- name: Validate YAML files
run: |
set -euo pipefail

python scripts/validate_yaml.py

- name: Validate shell scripts
run: |
set -euo pipefail

mapfile -d '' shell_files < <(
git ls-files -z -- '*.sh' '*.bash'
)

if (( ${#shell_files[@]} == 0 )); then
echo "No shell scripts found. Skipping shellcheck."
exit 0
fi

failed=0

for file in "${shell_files[@]}"; do
echo "Running shellcheck on ${file}"
if ! shellcheck "${file}"; then
failed=1
fi
done

exit "$failed"

- name: Validate JSON files
run: |
set -euo pipefail
failed=0

while IFS= read -r -d '' file; do
echo "Validating JSON: ${file}"

if ! python -m json.tool "${file}" > /dev/null 2>&1; then
echo "FAILED: Invalid JSON in ${file}"
failed=1
fi
done < <(git ls-files -z -- '*.json')

exit "$failed"

- name: Validate Markdown structure
run: |
set -euo pipefail

config_file="${RUNNER_TEMP}/markdownlint-cli2.jsonc"

cat > "${config_file}" <<'EOF'
{
"config": {
Expand All @@ -135,72 +108,60 @@ jobs:
}
}
EOF

mapfile -d '' markdown_files < <(git ls-files -z -- '*.md')

if (( ${#markdown_files[@]} == 0 )); then
echo "No Markdown files found. Skipping markdownlint."
exit 0
fi

markdownlint-cli2 --config "${config_file}" "${markdown_files[@]}"

- name: Validate Markdown tables
run: |
set -euo pipefail

python scripts/validate_markdown_tables.py

- name: Check internal Markdown links
run: |
set -euo pipefail

python scripts/check_internal_markdown_links.py

- name: Check external Markdown links
continue-on-error: true
run: |
set -euo pipefail

config_file="${RUNNER_TEMP}/markdown-link-check-external.json"

cat > "${config_file}" <<'EOF'
{
"ignorePatterns": [
{
"pattern": "^(?!https?:\\/\\/)"
},
{
"pattern": "^https?://www\\.linkedin\\.com"
},
{
"pattern": "^https?://owasp\\.slack\\.com"
}
],
"timeout": "10s",
"retryOn429": true,
"retryCount": 2
"retryCount": 2,
"aliveStatusCodes": [200, 403]
}
EOF

failed=0

while IFS= read -r -d '' file; do
echo "Checking external links in ${file}"

if ! markdown-link-check "${file}" --quiet --config "${config_file}"; then
failed=1
fi
done < <(git ls-files -z -- '*.md')

exit "$failed"

- name: Check generated artifacts are up to date
run: |
set -euo pipefail

python scripts/check_generated_artifacts.py

- name: Check for temporary or debug files
run: |
set -euo pipefail

failed=0

while IFS= read -r -d '' file; do
case "${file}" in
*.tmp|*.bak|*.log|*.swp|*.swo|*.orig|.DS_Store)
Expand All @@ -209,5 +170,4 @@ jobs:
;;
esac
done < <(git ls-files -z)

exit "$failed"
2 changes: 1 addition & 1 deletion ACKNOWLEDGEMENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ The following standards and frameworks directly informed the development of APTS
- [OWASP ASVS](https://owasp.org/www-project-application-security-verification-standard/) (Application Security Verification Standard)
- [OSSTMM](https://www.isecom.org/OSSTMM.3.pdf) (Open Source Security Testing Methodology Manual)
- [OWASP Top 10 for Agentic Applications](https://genai.owasp.org/resource/owasp-top-10-for-agentic-applications-for-2026/) (Agentic AI Security Risks)
- [NIST AI RMF](https://www.nist.gov/artificial-intelligence/risk-management-framework) (AI Risk Management Framework)
- [NIST AI RMF](https://www.nist.gov/itl/ai-risk-management-framework) (AI Risk Management Framework)
- [EU AI Act](https://artificialintelligenceact.eu/) (Regulation (EU) 2024/1689)

## How to Get Listed
Expand Down
2 changes: 1 addition & 1 deletion LICENSE.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,4 +193,4 @@ Original work licensed under CC BY-SA 4.0: https://github.com/OWASP/APTS

## OWASP Trademark

The OWASP name and logos are trademarks of The OWASP Foundation. You may refer to the standard as "OWASP Autonomous Penetration Testing Standard" for editorial purposes without permission. Commercial use of OWASP trademarks requires approval. Contact [trademarks@owasp.org](mailto:trademarks@owasp.org). See the [OWASP Trademark Policy](https://owasp.org/www-policy/operational/trademark) for details.
The OWASP name and logos are trademarks of The OWASP Foundation. You may refer to the standard as "OWASP Autonomous Penetration Testing Standard" for editorial purposes without permission. Commercial use of OWASP trademarks requires approval. Contact [trademarks@owasp.org](mailto:trademarks@owasp.org). See the [OWASP Trademark Policy](https://owasp.org/www-policy/operational/mark-usage-guidelines) for details.
Loading