Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
3b8c5d5
chore: prepare v1.0.0 release
r-pedraza Jan 12, 2026
c6fa9cd
feat: implement GitHub-based plugin marketplace system
r-pedraza Jan 13, 2026
b1fbcf5
feat: implement dynamic plugin configuration with JSON Schema
r-pedraza Jan 13, 2026
0de8d7f
feat: add Browse Plugin Marketplace to interactive menu
r-pedraza Jan 13, 2026
169d999
refactor: change plugins to project-level installation
r-pedraza Jan 13, 2026
c48ef98
fix: use MenuItem.action instead of MenuItem.value in marketplace
r-pedraza Jan 13, 2026
0376e29
fix: apply critical code review fixes
r-pedraza Jan 13, 2026
4f22573
refactor(plugins): centralize marketplace messages
r-pedraza Jan 13, 2026
98cdf16
refactor(plugins): remove redundant configuration prompt in marketplace
r-pedraza Jan 13, 2026
b5f582a
fix(plugins): correct repository name in plugin download path
r-pedraza Jan 13, 2026
a402571
fix(plugins): handle branch name slashes in ZIP extraction
r-pedraza Jan 13, 2026
760e53c
fix(plugins): add missing ask_password method to PromptsRenderer
r-pedraza Jan 13, 2026
12e1469
fix(plugins): fix PromptsRenderer method signatures in config wizard
r-pedraza Jan 13, 2026
c2b113b
fix(plugins): correct ask_confirm parameter to use question=
r-pedraza Jan 14, 2026
b40b7b2
fix: prevent duplicate plugins in discovery list
r-pedraza Jan 14, 2026
389674e
chore: prepare plugin marketplace for merge to master
r-pedraza Jan 14, 2026
e7c8ba8
Merge branch 'master' of https://github.com/masmovil/titan-cli into f…
r-pedraza Jan 14, 2026
3b9bd3c
feat(plugins_marketplace): fix problems with merge
r-pedraza Jan 14, 2026
7f5c109
refactor(plugins): centralize all hardcoded messages in core modules
r-pedraza Jan 14, 2026
2e64749
chore(plugins): fix linting warnings in plugin core modules
r-pedraza Jan 14, 2026
e2f1c8e
fix(tests): remove unused variable and imports in config_schema_rende…
r-pedraza Jan 14, 2026
54ba497
feat(plugins): add plugin marketplace core functionality
r-pedraza Jan 16, 2026
a628a02
docs(plugins): add comprehensive plugin system documentation
r-pedraza Jan 16, 2026
d5cab3d
ci(plugins): add automated workflows and tooling scripts
r-pedraza Jan 16, 2026
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
130 changes: 130 additions & 0 deletions .github/workflows/publish-plugins.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
name: Publish Plugins to PyPI
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Info IaC Finding

Workflow should have permissions limitations
on resource name

More Details
This rule checks that GitHub workflow has an empty permissions block to enforce least privilege. This rule fails when the workflow doesn't have a permissions block or has a non-empty permissions block with `write-all` scope, which can grant excessive permissions to workflow actions. Excessive permissions in GitHub workflows increase the risk surface in case of a compromise, potentially allowing attackers to access sensitive resources or perform unauthorized actions. To prevent this risk, always implement least privilege by explicitly defining an empty permissions block for all workflows.

Expected

GitHub workflow should have empty permissions block

Found

GitHub workflow doesn't have a permissions block defined

Security Frameworks: wf-id-1, wf-id-175


Rule ID: 65570021-8e03-4ccf-bf86-6bcb9fcc7a97


To ignore this finding as an exception, reply to this conversation with #wiz_ignore reason

If you'd like to ignore this finding in all future scans, add an exception in the .wiz file (learn more) or create an Ignore Rule (learn more).


To get more details on how to remediate this issue using AI, reply to this conversation with #wiz remediate


on:
push:
tags:
- 'plugin-git-v*'
- 'plugin-github-v*'
- 'plugin-jira-v*'
- 'plugin-*-v*' # Support new plugins
workflow_dispatch:
inputs:
plugin:
description: 'Plugin name (e.g., git, github, jira)'
required: true
version:
description: 'Version to release (e.g., 1.0.0)'
required: true

jobs:
determine-plugin:
runs-on: ubuntu-latest
outputs:
plugin-name: ${{ steps.extract.outputs.plugin-name }}
plugin-version: ${{ steps.extract.outputs.version }}
steps:
- name: Extract plugin from tag
id: extract
run: |
# Handle both manual dispatch and tag-triggered workflow
if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
PLUGIN="${{ github.event.inputs.plugin }}"
VERSION="${{ github.event.inputs.version }}"
else
TAG="${{ github.ref }}"
# Extract from tag: plugin-git-v1.0.0 -> git, 1.0.0
PLUGIN=$(echo "$TAG" | sed 's|refs/tags/plugin-||;s|-v.*||')
VERSION=$(echo "$TAG" | sed 's|refs/tags/.*-v||')
fi

echo "plugin-name=$PLUGIN" >> $GITHUB_OUTPUT
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Plugin: $PLUGIN, Version: $VERSION"

publish:
needs: determine-plugin
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Full history for git operations

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'

- name: Install Poetry
uses: snok/install-poetry@v1
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Low IaC Finding

Workflow should not use version pinning for third-party actions
on resource jobs.publish.steps[2].uses

More Details
This rule checks that GitHub workflow does not use version pinning on third-party actions. This rule fails when the workflow contains steps that use third-party actions referenced by version tags (like @v1, @v2.3, @v4) instead of specific commits. Using version-tagged actions creates a supply chain security risk, as the version tag could be modified by the action's maintainer to point to malicious code after the calling workflow is created. Even when using specific version tags, the tag could be moved to point to malicious code. To prevent this risk, always pin third-party actions to specific commit SHAs to ensure the exact code being executed is locked and immutable.

Expected

Workflow job 'publish' step[2] should pin third-party action to a commit SHA rather than a version tag

Found

Workflow job 'publish' step[2] uses version-tagged third-party action: 'snok/install-poetry@v1'

Security Frameworks: wf-id-1, wf-id-175


Rule ID: 7d431072-4eef-466b-b469-4b7681d8f9a1


To ignore this finding as an exception, reply to this conversation with #wiz_ignore reason

If you'd like to ignore this finding in all future scans, add an exception in the .wiz file (learn more) or create an Ignore Rule (learn more).


To get more details on how to remediate this issue using AI, reply to this conversation with #wiz remediate

with:
version: latest

- name: Update plugin version in pyproject.toml
working-directory: plugins/titan-plugin-${{ needs.determine-plugin.outputs.plugin-name }}
run: |
poetry version ${{ needs.determine-plugin.outputs.plugin-version }}

- name: Build plugin package
working-directory: plugins/titan-plugin-${{ needs.determine-plugin.outputs.plugin-name }}
run: poetry build

- name: Publish to PyPI
working-directory: plugins/titan-plugin-${{ needs.determine-plugin.outputs.plugin-name }}
run: poetry publish
env:
POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_TOKEN }}

update-registry:
needs: [determine-plugin, publish]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'

- name: Update registry.json
run: |
python scripts/update_registry.py \
--plugin titan-plugin-${{ needs.determine-plugin.outputs.plugin-name }} \
--version ${{ needs.determine-plugin.outputs.plugin-version }}

- name: Commit registry update
run: |
git config user.email "titan-bot@masmovil.es"
git config user.name "Titan Bot"
git add registry.json
git diff --cached --exit-code || {
git commit -m "chore(registry): update titan-plugin-${{ needs.determine-plugin.outputs.plugin-name }} to v${{ needs.determine-plugin.outputs.plugin-version }}"
git push
}

- name: Create Release Notes
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: plugin-${{ needs.determine-plugin.outputs.plugin-name }}-v${{ needs.determine-plugin.outputs.plugin-version }}
release_name: Plugin ${{ needs.determine-plugin.outputs.plugin-name }} v${{ needs.determine-plugin.outputs.plugin-version }}
body: |
## Plugin Release

**Plugin**: `titan-plugin-${{ needs.determine-plugin.outputs.plugin-name }}`
**Version**: `${{ needs.determine-plugin.outputs.plugin-version }}`
**Status**: ✅ Published to PyPI

### Installation

```bash
pipx inject titan-cli titan-plugin-${{ needs.determine-plugin.outputs.plugin-name }}
```

### Registry

The marketplace registry has been automatically updated.
draft: false
prerelease: false
98 changes: 98 additions & 0 deletions .github/workflows/test-plugins.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
name: Test Plugins
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Info IaC Finding

Workflow should have permissions limitations
on resource name

More Details
This rule checks that GitHub workflow has an empty permissions block to enforce least privilege. This rule fails when the workflow doesn't have a permissions block or has a non-empty permissions block with `write-all` scope, which can grant excessive permissions to workflow actions. Excessive permissions in GitHub workflows increase the risk surface in case of a compromise, potentially allowing attackers to access sensitive resources or perform unauthorized actions. To prevent this risk, always implement least privilege by explicitly defining an empty permissions block for all workflows.

Expected

GitHub workflow should have empty permissions block

Found

GitHub workflow doesn't have a permissions block defined

Security Frameworks: wf-id-1, wf-id-175


Rule ID: 65570021-8e03-4ccf-bf86-6bcb9fcc7a97


To ignore this finding as an exception, reply to this conversation with #wiz_ignore reason

If you'd like to ignore this finding in all future scans, add an exception in the .wiz file (learn more) or create an Ignore Rule (learn more).


To get more details on how to remediate this issue using AI, reply to this conversation with #wiz remediate


on:
pull_request:
paths:
- 'plugins/**'
- '.github/workflows/test-plugins.yml'
push:
branches:
- develop
- feat/**
paths:
- 'plugins/**'

jobs:
detect-plugins:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- uses: actions/checkout@v4

- name: Detect changed plugins
id: set-matrix
run: |
# Get list of changed files
if [ "${{ github.event_name }}" == "pull_request" ]; then
CHANGED_FILES=$(git diff --name-only ${{ github.event.pull_request.base.sha }}...HEAD)
else
CHANGED_FILES=$(git diff --name-only HEAD~1..HEAD)
fi

# Extract unique plugin directories
PLUGINS=()
for file in $CHANGED_FILES; do
if [[ $file == plugins/titan-plugin-*/* ]]; then
PLUGIN=$(echo $file | cut -d'/' -f2)
if [[ ! " ${PLUGINS[@]} " =~ " ${PLUGIN} " ]]; then
PLUGINS+=("$PLUGIN")
fi
fi
done

# If no plugins detected, test all
if [ ${#PLUGINS[@]} -eq 0 ]; then
PLUGINS=("titan-plugin-git" "titan-plugin-github" "titan-plugin-jira")
fi

# Format as JSON array
MATRIX=$(printf '"%s",' "${PLUGINS[@]}" | sed 's/,$//')
MATRIX="{\"plugin\":[$MATRIX]}"
echo "matrix=$MATRIX" >> $GITHUB_OUTPUT

test:
needs: detect-plugins
runs-on: ubuntu-latest
strategy:
matrix: ${{ fromJson(needs.detect-plugins.outputs.matrix) }}
fail-fast: false
steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'

- name: Install Poetry
uses: snok/install-poetry@v1
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Low IaC Finding

Workflow should not use version pinning for third-party actions
on resource jobs.test.steps[2].uses

More Details
This rule checks that GitHub workflow does not use version pinning on third-party actions. This rule fails when the workflow contains steps that use third-party actions referenced by version tags (like @v1, @v2.3, @v4) instead of specific commits. Using version-tagged actions creates a supply chain security risk, as the version tag could be modified by the action's maintainer to point to malicious code after the calling workflow is created. Even when using specific version tags, the tag could be moved to point to malicious code. To prevent this risk, always pin third-party actions to specific commit SHAs to ensure the exact code being executed is locked and immutable.

Expected

Workflow job 'test' step[2] should pin third-party action to a commit SHA rather than a version tag

Found

Workflow job 'test' step[2] uses version-tagged third-party action: 'snok/install-poetry@v1'

Security Frameworks: wf-id-1, wf-id-175


Rule ID: 7d431072-4eef-466b-b469-4b7681d8f9a1


To ignore this finding as an exception, reply to this conversation with #wiz_ignore reason

If you'd like to ignore this finding in all future scans, add an exception in the .wiz file (learn more) or create an Ignore Rule (learn more).


To get more details on how to remediate this issue using AI, reply to this conversation with #wiz remediate

with:
version: latest
virtualenvs-in-project: true

- name: Load cached venv
id: cached-poetry-dependencies
uses: actions/cache@v3
with:
path: plugins/${{ matrix.plugin }}/.venv
key: venv-${{ matrix.plugin }}-${{ hashFiles(format('plugins/{0}/poetry.lock', matrix.plugin)) }}

- name: Install dependencies
working-directory: plugins/${{ matrix.plugin }}
run: poetry install

- name: Run linting (ruff)
working-directory: plugins/${{ matrix.plugin }}
run: poetry run ruff check . --output-format=short

- name: Run tests
working-directory: plugins/${{ matrix.plugin }}
run: poetry run pytest -v

- name: Upload coverage
uses: codecov/codecov-action@v3
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Low IaC Finding

Workflow should not use version pinning for third-party actions
on resource jobs.test.steps[7].uses

More Details
This rule checks that GitHub workflow does not use version pinning on third-party actions. This rule fails when the workflow contains steps that use third-party actions referenced by version tags (like @v1, @v2.3, @v4) instead of specific commits. Using version-tagged actions creates a supply chain security risk, as the version tag could be modified by the action's maintainer to point to malicious code after the calling workflow is created. Even when using specific version tags, the tag could be moved to point to malicious code. To prevent this risk, always pin third-party actions to specific commit SHAs to ensure the exact code being executed is locked and immutable.

Expected

Workflow job 'test' step[7] should pin third-party action to a commit SHA rather than a version tag

Found

Workflow job 'test' step[7] uses version-tagged third-party action: 'codecov/codecov-action@v3'

Security Frameworks: wf-id-1, wf-id-175


Rule ID: 7d431072-4eef-466b-b469-4b7681d8f9a1


To ignore this finding as an exception, reply to this conversation with #wiz_ignore reason

If you'd like to ignore this finding in all future scans, add an exception in the .wiz file (learn more) or create an Ignore Rule (learn more).


To get more details on how to remediate this issue using AI, reply to this conversation with #wiz remediate

with:
files: ./plugins/${{ matrix.plugin }}/coverage.xml
flags: plugins
fail_ci_if_error: false
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,6 @@ venv.bak/
# OS-specific
.DS_Store
Thumbs.db

# Titan CLI - Downloaded plugins (project-level)
.titan/plugins/
Loading