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
20 changes: 15 additions & 5 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,12 @@ jobs:
distribution: temurin
java-version: 25

- name: 🐳 Check Docker
shell: sh
run: |
docker version
docker info

- name: 🏷️ Prepare release metadata
if: steps.plan.outputs.release == 'true'
shell: sh
Expand Down Expand Up @@ -309,11 +315,11 @@ jobs:
fi
curl "$@" https://plugins.jetbrains.com/api/updates/upload

- name: 📤 Push release commit and tag
- name: 📤 Push release commit
id: release_source
if: steps.plan.outputs.release == 'true' && steps.plan.outputs.dry_run != 'true'
shell: sh
env:
RELEASE_TAG: ${{ steps.plan.outputs.tag }}
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
run: |
git config user.name "Kira"
Expand All @@ -324,9 +330,9 @@ jobs:
fi

target_branch="${GITHUB_REF_NAME:-main}"
release_target="$(git rev-parse HEAD)"
git push origin "HEAD:$target_branch"
git tag -a "$RELEASE_TAG" -m "$RELEASE_TAG [skip ci]"
git push origin "refs/tags/$RELEASE_TAG"
echo "target=$release_target" >> "$GITHUB_OUTPUT"

- name: 🚀 Create GitHub release
if: steps.plan.outputs.release == 'true' && steps.plan.outputs.dry_run != 'true'
Expand All @@ -335,12 +341,16 @@ jobs:
ARCHIVE_PATH: ${{ steps.archive.outputs.path }}
GH_TOKEN: ${{ secrets.RELEASE_TOKEN || github.token }}
RELEASE_TAG: ${{ steps.plan.outputs.tag }}
RELEASE_TARGET: ${{ steps.release_source.outputs.target }}
run: |
if gh release view "$RELEASE_TAG" >/dev/null 2>&1; then
gh release upload "$RELEASE_TAG" "$ARCHIVE_PATH" --clobber
gh release edit "$RELEASE_TAG" --title "$RELEASE_TAG" --notes-file release-notes.md
else
gh release create "$RELEASE_TAG" "$ARCHIVE_PATH" --title "$RELEASE_TAG" --notes-file release-notes.md --verify-tag
if ! gh release create "$RELEASE_TAG" "$ARCHIVE_PATH" --title "$RELEASE_TAG" --notes-file release-notes.md --target "$RELEASE_TARGET"; then
gh release delete "$RELEASE_TAG" --yes --cleanup-tag >/dev/null 2>&1 || true
exit 1
fi
fi

- name: 💾 Save cache
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
- Updated the IntelliJ test platform, JaCoCo, and GitHub Actions cache action to current stable metadata.
- Fixed the README build badge link and refreshed navigation/release docs.
- `.gitea/workflows/*` files now get their own light/dark Gitea-flavored file icon instead of cosplaying GitHub.
- Gitea workflow runs now use `GITEA_TOKEN`-style auth, clean browser links, and repo-level run discovery for `/api/v1`.
- `.gitea/workflows/*` syntax now uses Gitea permission scopes and cron aliases instead of GitHub-only scope clutter.
- `.gitea/workflows/*` completion and validation now know `GITEA_TOKEN`, Gitea runner env vars, single-label `runs-on`,
documented expression functions, and job keys Gitea accepts but ignores.

## [2026.5.29] - 2026-05-29

Expand Down
17 changes: 15 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,30 @@ _[See Screenshots](https://plugins.jetbrains.com/plugin/21396-github-workflow)_
matching IDE accounts first, then other IDE GitHub accounts, then `GITHUB_TOKEN`, `GH_TOKEN`, `GITHUB_PAT`, then
anonymous access. An optional token environment variable can still be set explicitly for custom setups. GitHub log
timestamps, groups, command markers, and ANSI color codes are compacted before display.
* **Usage**: Enjoy autocomplete, syntax highlighting, and much more as you code your GitHub Workflows and Actions.
* **Usage**: Enjoy autocomplete, syntax highlighting, and much more as you code GitHub or Gitea Workflows and Actions.

## Local Development

The project uses the Gradle wrapper and Java 25. No manual JetBrains JDK path is needed; the IntelliJ Platform Gradle
Plugin downloads the IDE, bundled plugins, verifier, and test runtime.

1. Install Java 25 and make it available as `java`.
2. Run `./gradlew test` for the fast regression suite.
2. Run `./gradlew test` for the regression suite, including the Docker-backed Gitea smoke test.
3. Run `./gradlew check verifyPlugin buildPlugin` before publishing or opening a release PR.

Gitea smoke test controls:

```sh
./gradlew test --tests com.github.yunabraska.githubworkflow.git.GiteaDockerIntegrationTest --rerun-tasks
GITEA_DOCKER_TEST=false ./gradlew test
```

That starts the official rootless Gitea Docker image, seeds a tiny repository, and checks action plus `.gitea/workflows`
metadata through the same remote resolver. Set `GITEA_DOCKER_TEST=false` to skip it locally, or override the image with
`GITEA_IMAGE` when testing another Gitea release. If `docker` is not on the Gradle process `PATH`, set
`GITEA_DOCKER_BIN`, `DOCKER_BIN`, or `DOCKER_CLI` to the Docker executable; the test also tries `command -v docker`,
`which docker`, `where docker`, and common Docker Desktop/Homebrew locations.

## Release Automation

One workflow handles tagging, packaging, GitHub Packages, Marketplace publishing, changelog notes, and GitHub releases.
Expand Down
7 changes: 7 additions & 0 deletions doc/adr/0002-configurable-remote-action-providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,18 @@ tokens.
Use a JDK fake HTTP server in tests for GitHub Enterprise-shaped API behavior. Tests may inject temporary server
definitions directly into the service; that is not a user-facing settings surface.

Reuse the same provider boundary for Gitea-compatible API behavior where possible. Gitea differs by using `/api/v1` and
`Authorization: token ...`, so tests cover that provider type explicitly. Do not add a Gitea account UI unless real
user-facing configuration becomes necessary.

## Consequences

Self-hosted GitHub action metadata can be resolved, linked, highlighted, styled, documented, and completed without
contacting public GitHub in tests.

Gitea action and `.gitea/workflows` metadata can be tested through fake `/api/v1` responses and a default-on Docker
smoke test without duplicating the GitHub resolver. `GITEA_DOCKER_TEST=false` keeps local escape hatches explicit.

The plugin stays boring: no duplicate account UI, no token storage, and fewer settings to test.

The provider currently resolves metadata and refs after a callable is known. It does not browse arbitrary remote
Expand Down
1 change: 1 addition & 0 deletions doc/navigation.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ Editor behavior should be tested through IntelliJ fixture entrypoints. See:

- `doc/adr/0008-test-through-editor-and-runtime-boundaries.md`
- `doc/spec/editor-test-matrix.md`
- `doc/spec/gitea-github-actions-compatibility.md`

Remote GitHub behavior should use fake HTTP servers or explicit client boundaries. Network access in tests is guilty
until proven innocent.
6 changes: 6 additions & 0 deletions doc/spec/editor-test-matrix.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ Official syntax references:
- Resolved actions with cached major-version refs show an update quick-fix for older `v?\d+` refs.
- Remote `uses` ref completion for tags/branches resolved from public GitHub and GitHub Enterprise-shaped servers
through fake HTTP servers.
- Gitea-compatible `/api/v1` remote metadata resolution is covered through fake HTTP tests and a default-on Docker smoke
test against the official rootless Gitea image. The same Docker suite also registers `act_runner`, dispatches a real
`.gitea/workflows` run through the plugin client, waits for completion, lists jobs, and downloads logs. Set
`GITEA_DOCKER_TEST=false` to skip it.
- GitHub Enterprise servers registered in JetBrains GitHub settings are used as remote metadata sources; the plugin does
not add a parallel server settings UI.
- Cache actions and settings are registered through `plugin.xml`, localized through resource bundles, and covered by
Expand Down Expand Up @@ -56,6 +60,8 @@ Official syntax references:
`runner.*`, including `runner.debug`, `job.*`, nested `job.container.*`, strict local `job.services.*`, `strategy.*`,
`matrix.*`, and unknown external `vars.*` contexts.
- `gitea.*` context highlighting and completion uses the same key map as `github.*`.
- `.gitea/workflows/*` syntax uses Gitea token permission scopes, Gitea permission shorthand values, and Gitea cron
alias completion without leaking GitHub-only permission scopes from the bundled GitHub schema.
- `job.services.<service_id>` validation/completion/reference/styling from local job service definitions, including `id`, `network`, `ports`, and mapped port keys.
- Matrix keys from direct `strategy.matrix` entries and `strategy.matrix.include`.
- `steps.<id>.outputs.<name>` validation and completion for previous run outputs, multiline `$GITHUB_OUTPUT`, `tee -a $GITHUB_OUTPUT`, and resolved action outputs.
Expand Down
56 changes: 56 additions & 0 deletions doc/spec/gitea-github-actions-compatibility.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Gitea And GitHub Actions Compatibility

Last checked: 2026-06-11.

This note tracks behavior where Gitea Actions is close to GitHub Actions, but not identical. The plugin should prefer
shared behavior first and branch only where Gitea really differs. Tiny forks, not a hydra.

## Sources

- Gitea Actions comparison: https://docs.gitea.com/usage/actions/comparison
- Gitea Actions job token permissions: https://docs.gitea.com/usage/actions/token-permissions
- Gitea Actions variables and `gitea.*` context: https://docs.gitea.com/usage/actions/actions-variables
- Gitea API reference and OpenAPI spec: https://docs.gitea.com/api/
- Gitea OpenAPI source used for endpoint checks: https://docs.gitea.com/redocusaurus/plugin-redoc-1.yaml
- GitHub workflow REST API: https://docs.github.com/en/rest/actions/workflows?apiVersion=2026-03-10
- GitHub workflow run REST API: https://docs.github.com/en/rest/actions/workflow-runs?apiVersion=2026-03-10
- GitHub workflow job REST API: https://docs.github.com/en/rest/actions/workflow-jobs?apiVersion=2026-03-10
- GitHub artifact REST API: https://docs.github.com/en/rest/actions/artifacts?apiVersion=2026-03-10

## Already Handled

| Area | GitHub | Gitea | Plugin behavior |
| --- | --- | --- | --- |
| Workflow home | `.github/workflows/*` | `.gitea/workflows/*` | Both workflow roots are detected. |
| API base | `https://api.github.com` or enterprise `/api/v3` | Instance `/api/v1` | Run and metadata code infer provider behavior from API URL and workflow path. |
| API auth header | `Authorization: Bearer ...` | `Authorization: token ...` | Gitea providers and runs use `token ...`; GitHub keeps IDE account plus bearer token priority. |
| Token env fallback | `GITHUB_TOKEN`, `GH_TOKEN`, `GITHUB_PAT` | `GITEA_TOKEN`, `GITEA_PAT` | Gitea runs and metadata use Gitea token env names before anonymous access. |
| Workflow dispatch result | GitHub returns run details on current API version | Gitea returns run details when `return_run_details=true` | Gitea dispatch adds `return_run_details=true`; both parse `workflow_run_id`, `run_url`, and `html_url`. |
| Run discovery | Workflow-scoped or repository-scoped run listing | Repository-scoped `actions/runs` with `limit` and run `path` | GitHub keeps workflow-scoped discovery; Gitea reads a small repo-level window and picks the same workflow closest to dispatch time. |
| Job logs | `/actions/jobs/{job_id}/logs` | Same path in Gitea OpenAPI | Existing job log download path is shared. |
| Run jobs | `/actions/runs/{run}/jobs` | Same path in Gitea OpenAPI | Existing job tree polling path is shared. |
| Artifacts | Run artifact list plus artifact ZIP | Same core paths in Gitea OpenAPI | Existing artifact list/download path is shared. |
| Context root | `github.*` | `gitea.*`, with `github.*` as alias | Completion/highlighting covers `gitea.*` using the GitHub-compatible key map. |
| Absolute action URLs | GitHub syntax is usually `owner/repo[/path]@ref` | Absolute URLs are supported | Remote resolver supports absolute URLs for configured servers. |
| Cron aliases | GitHub uses POSIX cron expressions | Gitea also accepts `@yearly`, `@monthly`, `@weekly`, `@daily`, `@hourly` | `.gitea/workflows` cron completion suggests the Gitea aliases. |
| Permission scopes | GitHub has GitHub-only scopes such as `id-token`, `statuses`, `pages` | Gitea has `code`, `releases`, `wiki`, `projects`, and a smaller shared scope set | `.gitea/workflows` completion and validation use the Gitea scope set. |
| Permission shorthand | GitHub completion includes `read-all`, `write-all`, and `{}` | Gitea documents `read-all` and `write-all` scalar values | `.gitea/workflows` shorthand completion stays on documented Gitea values. |
| Complex `runs-on` | GitHub accepts richer runner targeting | Gitea supports scalar or single-item array forms | `.gitea/workflows` warns on multi-label arrays without affecting GitHub files. |
| Expression functions | GitHub has a wider function set | Gitea documents `always()` only | `.gitea/workflows` completion offers `always()` and warns on known GitHub-only functions. |
| Ignored job keys | GitHub executes `timeout-minutes`, `continue-on-error`, and `environment` | Gitea accepts but ignores them | `.gitea/workflows` keeps the keys valid and labels them as accepted runtime no-ops. |
| Runtime names | GitHub exposes `GITHUB_TOKEN` and `GITHUB_*` names | Gitea exposes `GITEA_TOKEN` and `GITEA_*` names too | `.gitea/workflows` completion prefers `secrets.GITEA_TOKEN` and includes Gitea runner env variables. |

## Known Limitations / Do Not Guess

| Area | Gitea behavior | Plugin risk | Suggested handling |
| --- | --- | --- | --- |
| Problem matchers and annotations | Gitea ignores problem matchers and workflow command annotations. | Log rendering can still color warnings/errors locally; remote UI may not. | No code change needed unless we add Gitea-specific docs. |
| Default action source | Gitea may resolve unqualified `uses:` through instance config (`github` or `self`). | Plugin cannot know server admin config. | Keep configured-server absolute URL support; do not guess admin config. |
| Secret and variable names | Gitea disallows user-created names starting with `GITHUB_` or `GITEA_`; variables are uppercased. | Future settings/UI for external variables must enforce Gitea naming rules. | Built-in names are completed; external variable CRUD does not exist yet. |

## Test Shape

- Fake HTTP tests cover provider inference, auth header scheme, dispatch URL, and run discovery URL.
- The Docker-backed Gitea integration test runs by default and seeds tiny repositories to verify `/api/v1` metadata
resolution plus a real `act_runner` workflow dispatch, run completion, job listing, and log download.
- Keep Docker test opt-out explicit with `GITEA_DOCKER_TEST=false` for machines where Docker is unavailable.
Loading