- Shell 100%
|
All checks were successful
Lint / shellcheck (push) Successful in 3s
Tests all four actions in sequence: create task with reference, find it, comment by ID, comment by reference, close by reference, then close again to verify idempotency. Uses the workflow run ID as a unique reference to avoid collisions between test runs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .forgejo/workflows | ||
| action.yml | ||
| CLAUDE.md | ||
| entrypoint.sh | ||
| NEXT_STEPS.md | ||
| README.md | ||
Create Vikunja Task
A Forgejo Action that creates a task in Vikunja with optional labels, assignees, priority, due date, and kanban bucket placement.
All inputs accept human-readable names (project names, usernames, label names) -- the action resolves them to IDs automatically via the Vikunja API.
Setup
1. Create a Vikunja API token
In Vikunja: Settings > API Tokens -- create a token with write access.
2. Set secrets
Add these secrets at the org or repo level in Forgejo (Settings > Actions > Secrets):
| Secret | Required | Example |
|---|---|---|
VIKUNJA_API_URL |
yes | https://todo.example.com |
VIKUNJA_API_TOKEN |
yes | tk_abc123... |
VIKUNJA_PROJECT |
yes | Inbox |
Note: User-level secrets do not cascade into organization repos. Set secrets at the org level for broad coverage, then override at the repo level as needed.
3. Override at repo level (optional)
Any secret can be overridden at the repo level. For example, set VIKUNJA_PROJECT on a specific repo to route its tasks to a different project, while inheriting VIKUNJA_API_URL and VIKUNJA_API_TOKEN from the org.
You can also set additional secrets to configure defaults for any input:
| Secret | Maps to input | Example |
|---|---|---|
VIKUNJA_ASSIGNEES |
assignees |
brad or brad,intern |
VIKUNJA_LABELS |
labels |
bug,urgent |
VIKUNJA_PRIORITY |
priority |
3 |
VIKUNJA_BUCKET |
bucket |
Backlog |
VIKUNJA_VIEW |
view |
Kanban |
Inputs
| Input | Required | Default | Description |
|---|---|---|---|
title |
yes | Task title | |
description |
no | "" |
Task description (supports markdown) |
project |
yes* | "" |
Project name (e.g. "Inbox") |
priority |
no | "" |
Priority: 1=low, 2=medium, 3=high, 4=urgent, 5=critical |
due-date |
no | "" |
Due date: ISO 8601 or YYYY-MM-DD |
labels |
no | "" |
Comma-separated label names (e.g. "bug,urgent") |
assignees |
no | "" |
Comma-separated usernames (e.g. "brad,intern") |
bucket |
no | "" |
Kanban bucket name (requires view too) |
view |
no | "" |
Project view name (e.g. "Kanban") |
api-url |
yes* | "" |
Vikunja base URL |
api-token |
yes* | "" |
Vikunja API token |
*Pass via ${{ secrets.VIKUNJA_* }} -- set at org level and override per-repo as needed.
Outputs
| Output | Description |
|---|---|
task-id |
Numeric ID of the created task |
task-url |
Full URL to the task in Vikunja |
Examples
Minimal
- uses: actions/vikunja-task@main
with:
title: "Deploy failed for ${{ github.repository }}"
api-url: ${{ secrets.VIKUNJA_API_URL }}
api-token: ${{ secrets.VIKUNJA_API_TOKEN }}
project: ${{ secrets.VIKUNJA_PROJECT }}
Create a task when a deploy fails
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: docker
steps:
- name: Deploy
run: ./deploy.sh
- name: Create task on failure
if: failure()
uses: actions/vikunja-task@main
with:
title: "Deploy failed: ${{ github.repository }}@${{ github.sha }}"
description: |
**Repo:** ${{ github.repository }}
**Branch:** ${{ github.ref_name }}
**Commit:** ${{ github.sha }}
**Run:** ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
priority: "4"
labels: "ci,deploy"
api-url: ${{ secrets.VIKUNJA_API_URL }}
api-token: ${{ secrets.VIKUNJA_API_TOKEN }}
project: ${{ secrets.VIKUNJA_PROJECT }}
Mirror Forgejo issues to Vikunja
name: Issue to Vikunja
on:
issues:
types: [opened]
jobs:
create-task:
runs-on: docker
steps:
- name: Create Vikunja task from issue
uses: actions/vikunja-task@main
with:
title: "${{ github.event.issue.title }}"
description: |
${{ github.event.issue.body }}
---
*From issue ${{ github.event.issue.html_url }}*
assignees: ${{ secrets.VIKUNJA_ASSIGNEES }}
api-url: ${{ secrets.VIKUNJA_API_URL }}
api-token: ${{ secrets.VIKUNJA_API_TOKEN }}
project: ${{ secrets.VIKUNJA_PROJECT }}
With priority, due date, and kanban placement
- uses: actions/vikunja-task@main
id: task
with:
title: "Review PR #${{ github.event.pull_request.number }}"
description: "${{ github.event.pull_request.html_url }}"
priority: "3"
due-date: "2026-04-15"
labels: "review"
assignees: "brad"
view: "Kanban"
bucket: "In Progress"
api-url: ${{ secrets.VIKUNJA_API_URL }}
api-token: ${{ secrets.VIKUNJA_API_TOKEN }}
project: ${{ secrets.VIKUNJA_PROJECT }}
- name: Comment task link
run: echo "Created task ${{ steps.task.outputs.task-url }}"
Wire all secrets through for full cascade
Set secrets at different levels (org, repo) and pass them all through. Any that aren't set resolve to empty and get skipped:
- uses: actions/vikunja-task@main
with:
title: "Task from CI"
api-url: ${{ secrets.VIKUNJA_API_URL }}
api-token: ${{ secrets.VIKUNJA_API_TOKEN }}
project: ${{ secrets.VIKUNJA_PROJECT }}
assignees: ${{ secrets.VIKUNJA_ASSIGNEES }}
labels: ${{ secrets.VIKUNJA_LABELS }}
bucket: ${{ secrets.VIKUNJA_BUCKET }}
view: ${{ secrets.VIKUNJA_VIEW }}
priority: ${{ secrets.VIKUNJA_PRIORITY }}
Secret Cascade
Forgejo resolves secrets repo > org. Set base config at the org level, override per-repo:
| Level | VIKUNJA_PROJECT |
VIKUNJA_ASSIGNEES |
Effect |
|---|---|---|---|
| Org (actions) | Inbox |
(empty) | Default: tasks go to Inbox, unassigned |
| Org (mysteryhound) | Mystery Hound |
brad |
Overridden: tasks go to Mystery Hound, assigned to brad |
| Repo (mh-backend) | (inherits) | intern |
Only assignee overridden: still Mystery Hound, but assigned to intern |
A workflow step can also hard-code overrides alongside secret-backed defaults:
assignees: "intern" # hard-coded override
priority: "4" # hard-coded override
project: ${{ secrets.VIKUNJA_PROJECT }} # from cascade
Requirements
The runner must have curl, jq, and bash installed.
License
MIT