From 047c4c9b219056fb386ac5fe21b68d1ed54d3f75 Mon Sep 17 00:00:00 2001 From: Hannes Papenberg Date: Tue, 23 Jun 2026 09:45:49 +0200 Subject: [PATCH 1/4] Adding initial commit for extension development setup --- .../development/checklist.md | 41 +++++++++++++++++ .../building-extensions/development/checks.md | 22 +++++++++ docs/building-extensions/development/ci.md | 0 docs/building-extensions/development/ide.md | 0 docs/building-extensions/development/index.md | 45 +++++++++++++++++++ .../development/release.md | 0 docs/building-extensions/development/repo.md | 12 +++++ .../development/testing.md | 0 8 files changed, 120 insertions(+) create mode 100644 docs/building-extensions/development/checklist.md create mode 100644 docs/building-extensions/development/checks.md create mode 100644 docs/building-extensions/development/ci.md create mode 100644 docs/building-extensions/development/ide.md create mode 100644 docs/building-extensions/development/index.md create mode 100644 docs/building-extensions/development/release.md create mode 100644 docs/building-extensions/development/repo.md create mode 100644 docs/building-extensions/development/testing.md diff --git a/docs/building-extensions/development/checklist.md b/docs/building-extensions/development/checklist.md new file mode 100644 index 00000000..8e565e12 --- /dev/null +++ b/docs/building-extensions/development/checklist.md @@ -0,0 +1,41 @@ +--- +title: Step-by-step list to setup a development environment for an existing extension +--- + +Step-by-step list to setup a development environment for an existing extension +================= + +1. Create a folder for your repository +2. Create a project on Github or your git manager of choice +3. Clone the git repository into your folder or initialise a new git repository with `git init` +4. Run `composer require --dev joomla-projects/jorobo` in the folder +5. Run `vendor/bin/jorobo init` in the folder and say `yes` to use all features. You now have `php-cs-fixer`, `phpcs` for codestyle, `phpstan` for static codeanalysis, `phpunit` for unittests, `JoRobo` for release packaging and some additional tasks, `.gitignore` and `.editorconfig` for your IDE configured, as well as a `/src` folder for your source code. +6. Run `vendor/bin/jorobo ci` in the folder and select if you want to insert a setup for a Github Actions or Gitlab CI setup. +7. Modify your `jorobo.dist.ini` for your project +8. Commit all of this for your initial commit to your project. +9. Copy your unzipped extension into your `/src` folder and commit those files. Now you can go back to this first commit in case you messed something up. +10. Create a `/joomla` folder and add a copy of the Joomla version you want to support in it. This is used by the IDE, phpstan and rector to understand what the Joomla core classes are doing. This folder is already part of your `.gitignore` file. +11. Run `vendor/bin/php-cs-fixer fix` in the root of the project to get all your files to adhere to the PSR-12/PHP PER coding style. Commit the changes, create a `.git-blame-ignore-revs` and add the hash of the commit as one line in the file. This helps when using `blame` in git later when trying to find out who did what changes when. +12. Run `vendor/bin/jorobo rector` to install Rector to refactor your code automatically. It will create a default `rector.php` in the root of your project, which you have to modify. Please read the [documentation here](https://github.com/joomla-projects/jrector/blob/main/docs/index.md) to understand what you are doing! Run rector with `vendor/bin/rector --dry-run` to check the changes first and then without the parameter to actually do the modifications. After each run, check the modifications and commit them. + + If you have a non-namespaced extension, the following steps will help you with updating it to namespaces: + - The MVC rules creates a `rename.php`, which moves the files to their new places in the namespaced structure. Since rector decided against doing filesystem operations, this needs to be run separately by calling `php rename.php` in the root of your project. Remember to commit before and after moving the files, so that git keeps the connection between the old and new location and you retain the history across the move of the files. + - Now add the namespace to your extensions manifest file by adding `Your\Base\Namespace\Component\Componentname` to it. + - You are now still missing the `services/provider.php` in your components administrator folder. This you have to create manually. +13. Commit the changes to your repository and push them to your Github or Gitlab. Run `vendor/bin/php-cs-fixer fix` once more for good measure to ensure the changes by rector did not introduce new codestyle issues. +14. If your folder structure of your old extension does not follow the structure when installed in a Joomla installation, you should now move the admin part to `administrator/components/`, your site part to `components/` etc. Remember to commit that change. +15. Now would be the time that you really should open your project in PHPStorm if you haven't done so already. +16. Create a test installation of Joomla somewhere to test your extension. +17. Copy the content of your `/src` folder over the test installation to have all current project files in the right locations at this point. +18. Now we want to automatically copy all changes in our repository to the test installation. Go to `Settings -> Build, Execution, Deployment -> Deployment` and create a new deployment target with your test installation as target. Also set the `Mappings` and mark the deployment target as default. Go to `Settings -> Build, Execution, Deployment -> Deployment -> Options` and set `Upload changed files automatically to the default server` to `Always`. Now all modifications in PHPStorm will automatically show up in your test installation. +19. Now run `vendor/bin/phpstan` to get a report of all issues phpstan is finding. Fix them, commit, repeat until you are happy with the number of errors. +20. Discover your extension and test it in your test installation, fix all bugs you notice, commit after each bug, repeat until you are happy with the current state. +21. Run `vendor/bin/robo headers` to update all your copyright headers to the right structure you can defined in your `jorobo.dist.ini`. Pay attention that you are only changing the headers of your own code and not from third parties! Commit! +22. Modify your manifest file and replace the relevant parts with the placeholders from JoRobo defined in the documentation here. +23. Set the version in your manifest and wherever you else you need to set it, create a new tag and then run `vendor/bin/robo build`. You now have your installable extension package in your projects `/dist` folder. + +Congratulations, you now updated your Joomla 3 or later extension to the latest Joomla version, applied the standard codestyle for PHP projects, updated your code to PHP 8.1, don't have any deprecated code and now have a professional development environment including a CI system for each commit. + +New contributors to your extension only have to check out the repository and run `composer i` in the root of the project to have a working setup. Additonally you could create unit tests or add a system test setup with cypress to ensure your extension still works as expected after each change you do in the future. + +While all of these checks aren't a guarantee that your code is bug-free, it should greatly help increasing the quality of your extension and give you the opportunity to concentrate on providing new value with improved features to your users. diff --git a/docs/building-extensions/development/checks.md b/docs/building-extensions/development/checks.md new file mode 100644 index 00000000..0cf5786e --- /dev/null +++ b/docs/building-extensions/development/checks.md @@ -0,0 +1,22 @@ +Next one in the series: How to automatically check your extensions code. There are of course several different ways to check your code with static analysers. I'm just going to explain how I'm doing it with phpstan right now. phpstan can easily be installed via composer with `composer require --dev phpstan/phpstan` in the root of your site or your repo. You can then call it with `vendor/bin/phpstan` (or `vendor\bin\phpstan` for Windows) on the CLI in the respective root. If you are developing an extension in a git repo, I would advise to have all your code in a subfolder like `/src`, so that you can keep all the dev tools, configurations and documentation in the root (or folders below the root) of your repo. If you are checking the extension inside a site installation, you can still do that, but it requires a bit more work. Besides the initial `phpstan/phpstan` package, I would advise to also install `phpstan/phpstan-deprecation-rules` (with `composer require --dev phpstan/phpstan-deprecation-rules`) as well to get all deprecated code. + +phpstan can either be called with command line options or you can use a configuration file. I strongly recommend the later option and for the git repo solution described above, your config file could look like this: +``` +includes: + - vendor/phpstan/phpstan-deprecation-rules/rules.neon +parameters: + level: 0 + paths: + - src + scanDirectories: + - joomla + ignoreErrors: + reportUnmatchedIgnoredErrors: false +``` +What does this do? First of all, it include the deprecation rules. Then it defines the strictness level, which currently is set to its lowest. You can raise that step by step and ideally you should reach level 5 at some point. It then defines the paths to check. If you follow the structure that I proposed above for a git repo, you only have to define the single `/src` folder here. If you are checking an extension installed inside a site, you would have to list all paths here, like `components/com_test` and `administrator/components/com_test`. Of course you only need those folders, which contain PHP code. The next config option is then the information which additional folders to read for framework information. phpstan automatically reads the `/vendor` folder and with this option you can add additional code to this. In the above example, I copied a complete Joomla package into a subfolder `/joomla` of the repo and phpstan now can understand all references to classes in your code to that Joomla package. That way, you are teaching phpstan what all the Joomla core classes mean and do. At least in theory, because Joomla itself often enough is still struggling to provide code which a tool like phpstan can understand. + +Now you can call `vendor/bin/phpstan` on your code and will get a list of all things phpstan doesn't understand, considers wrong or reads as deprecated. Now comes the fun part of going through that code to fix stuff or make phpstan better understand it. Now don't dismiss the part about making phpstan understanding your code better, because it isn't just phpstan which will better understand your code, but also both you and your IDE. It is quite a difference when all of a sudden you notice that the object you got from a function call actually already contains the code you need instead of having to re-invent this. + +From my experience, there are 4 methods on how to improve your code. The first one is of course to prevent magic code, which might return different stuff with different text input. All those `$items = $this->get('Items');` in the views are horrible for this, because no analyser can find out what `$this->get()` actually returns. Avoid stuff like this where possible! The second method is to typehint variables. If instead of `$items = $this->get('Items');`, you use `$model = $this->getModel();$items = $model->getItems();`, you can now typehint that `$model` is a `Testeroo\Component\Site\Model\TestModel` class by adding `/** @var Testeroo\Component\Site\Model\TestModel $model */` somewhere in the file (preferably directly above the line where you are assigning `$model`). The third method is typehinting return method parameters and return values in your code directly. If your method shouldn't return anything, mark it as returning `void`. Which leads me to the fourth method and that comes into action when the typehinting capabilities of PHP are too limiting. In that case, you define those types in the docblocks. + +Adding phpstan to your project is easy and a matter of minutes, while I also was able to find a lot of bugs that way. Please give it a try. diff --git a/docs/building-extensions/development/ci.md b/docs/building-extensions/development/ci.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/building-extensions/development/ide.md b/docs/building-extensions/development/ide.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/building-extensions/development/index.md b/docs/building-extensions/development/index.md new file mode 100644 index 00000000..e79ef684 --- /dev/null +++ b/docs/building-extensions/development/index.md @@ -0,0 +1,45 @@ +--- +title: Sustainable Extension Development Setup +--- + +Sustainable Extension Development Setup +================= + +Unless you are writing a trivial extension and you are doing it just for a one-time quick test, you eventually run into the question how to make development easier, sustainable and professionell. +This section of the manual documents one way to setup a professional development setup, which allows you to do reliable coding, have a build script for your extensions and ensure quality with several tools. + +While this tutorial provides a full setup, you *don't* have to switch all of your current setup to this. Each part can be used separately and you can substitute each part with your own solution. + +This example is using Jetbrains PHPStorm as IDE and Github as storage and CI/CD solution, however you can of course use any other similar solution you want. The following setup description is here to not force you to reinvent the wheel for all of this, but to benefit from the works of others in this area. However there might be several reasons why you can't use one or the other tool in here and then you are encouraged to adapt this to your situation. + +## Storing your source code + +The first question is how to store your source code. While version control is a standard nowadays, how to structure the repository is still something which is left to the individual developer. +In this first chapter we are going through a possible structure of a git repository for your extension. + +To read more go to the [Repository Setup](repo.md). + +## IDE setup + +The next section handles the configuration of PHPStorm. + +To read more go to the [IDE Setup](ide.md). + +## Release handling + +With the setup of our repo and IDE we do have an extension to release. This section handles building a release with JoRobo. + +To read more go to the [Release handling](release.md). + +## Quality Assurance + +Learn how to use phpstan to find bugs and how a consistent codestyle can help you. + +To read more go to the [Quality Assurance setup](checks.md). + +## Automated testing + + +## Step-by-step list to create setup for an existing extension + +See the [Checklist](checklist.md). diff --git a/docs/building-extensions/development/release.md b/docs/building-extensions/development/release.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/building-extensions/development/repo.md b/docs/building-extensions/development/repo.md new file mode 100644 index 00000000..4e5489f8 --- /dev/null +++ b/docs/building-extensions/development/repo.md @@ -0,0 +1,12 @@ +# How to store your code + + + +## Extension and Repository Structure + +Creating an extension (or writing any code) isn't just tinkering with the code until it somehow works, but also keeping an overview of both your current changes and the changes over time. +Even in tiny, one-off projects, you want to see what changes you made in the last hour and for longer running projects, you want to have a log of what you have done last week or 2 months ago. +That is why you should **always** use a version control system. +It doesn't matter if it is git, mercury or even subversion, but you want to see all the changes you did since your last commit and of course you want to be able to understand what you thought last time you worked on this code by reading the commit messages. + +This tutorial concentrates on git and [Github.com](https://github.com). As of writing this tutorial, Github provides free unlimited public and private repositories diff --git a/docs/building-extensions/development/testing.md b/docs/building-extensions/development/testing.md new file mode 100644 index 00000000..e69de29b From 32d0f5d910c791450760ad006fb7e87103af91b2 Mon Sep 17 00:00:00 2001 From: Hannes Papenberg Date: Sun, 28 Jun 2026 14:55:03 +0200 Subject: [PATCH 2/4] Update docs/building-extensions/development/checklist.md Co-authored-by: Richard Fath --- docs/building-extensions/development/checklist.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/building-extensions/development/checklist.md b/docs/building-extensions/development/checklist.md index 8e565e12..4d0e8c60 100644 --- a/docs/building-extensions/development/checklist.md +++ b/docs/building-extensions/development/checklist.md @@ -23,7 +23,7 @@ Step-by-step list to setup a development environment for an existing extension - Now add the namespace to your extensions manifest file by adding `Your\Base\Namespace\Component\Componentname` to it. - You are now still missing the `services/provider.php` in your components administrator folder. This you have to create manually. 13. Commit the changes to your repository and push them to your Github or Gitlab. Run `vendor/bin/php-cs-fixer fix` once more for good measure to ensure the changes by rector did not introduce new codestyle issues. -14. If your folder structure of your old extension does not follow the structure when installed in a Joomla installation, you should now move the admin part to `administrator/components/`, your site part to `components/` etc. Remember to commit that change. +14. If your folder structure of your old extension does not follow the structure when installed in a Joomla installation, you should now move the admin part to `src/administrator/components/`, your site part to `src/components/` etc. Remember to commit that change. 15. Now would be the time that you really should open your project in PHPStorm if you haven't done so already. 16. Create a test installation of Joomla somewhere to test your extension. 17. Copy the content of your `/src` folder over the test installation to have all current project files in the right locations at this point. From 5a929bf4869334ca89ebcb128b0e2ca9365be3da Mon Sep 17 00:00:00 2001 From: Hannes Papenberg Date: Sun, 28 Jun 2026 14:55:18 +0200 Subject: [PATCH 3/4] Update docs/building-extensions/development/checklist.md Co-authored-by: Quy Ton --- docs/building-extensions/development/checklist.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/building-extensions/development/checklist.md b/docs/building-extensions/development/checklist.md index 4d0e8c60..e87b911d 100644 --- a/docs/building-extensions/development/checklist.md +++ b/docs/building-extensions/development/checklist.md @@ -32,7 +32,7 @@ Step-by-step list to setup a development environment for an existing extension 20. Discover your extension and test it in your test installation, fix all bugs you notice, commit after each bug, repeat until you are happy with the current state. 21. Run `vendor/bin/robo headers` to update all your copyright headers to the right structure you can defined in your `jorobo.dist.ini`. Pay attention that you are only changing the headers of your own code and not from third parties! Commit! 22. Modify your manifest file and replace the relevant parts with the placeholders from JoRobo defined in the documentation here. -23. Set the version in your manifest and wherever you else you need to set it, create a new tag and then run `vendor/bin/robo build`. You now have your installable extension package in your projects `/dist` folder. +23. Set the version in your manifest and wherever else you need to set it, create a new tag and then run `vendor/bin/robo build`. You now have your installable extension package in your projects `/dist` folder. Congratulations, you now updated your Joomla 3 or later extension to the latest Joomla version, applied the standard codestyle for PHP projects, updated your code to PHP 8.1, don't have any deprecated code and now have a professional development environment including a CI system for each commit. From d6ec23552479649c82331ef8ce34b1507e2e3dc8 Mon Sep 17 00:00:00 2001 From: Hannes Papenberg Date: Thu, 10 Sep 2026 14:28:25 +0200 Subject: [PATCH 4/4] Adding Release plans with JoRobo --- .../development/release.md | 398 ++++++++++++++++++ 1 file changed, 398 insertions(+) diff --git a/docs/building-extensions/development/release.md b/docs/building-extensions/development/release.md index e69de29b..a099739b 100644 --- a/docs/building-extensions/development/release.md +++ b/docs/building-extensions/development/release.md @@ -0,0 +1,398 @@ +# Release handling with JoRobo + +[JoRobo](https://github.com/joomla-projects/jorobo) is a task runner built on top of [Robo.li](https://robo.li/) that automates the most repetitive parts of Joomla extension development: building installable packages, maintaining copyright headers, bumping version numbers, generating changelogs, and publishing releases to GitHub or an FTP server. + +## Installation + +JoRobo is installed as a Composer dev dependency in the root of your extension repository: + +```bash +composer require --dev joomla-projects/jorobo +``` + +After the installation, run the built-in init command to create the required configuration files: + +```bash +vendor/bin/jorobo init +``` + +This creates a `jorobo.dist.ini` (and copies it to `jorobo.ini`) as well as a `RoboFile.php` in your repository root. + +:::note +`jorobo.ini` may contain secrets such as GitHub tokens. Add it to your `.gitignore` and commit only `jorobo.dist.ini` (without secrets) as a template for other contributors. +::: + +## Repository structure + +JoRobo expects your extension source code to live inside a `src/` folder at the root of your repository. Inside `src/`, mirror the directory structure of a Joomla installation exactly: + +``` +my-extension/ +├── src/ +│ ├── administrator/ +│ │ └── components/ +│ │ └── com_example/ +│ ├── components/ +│ │ └── com_example/ +│ ├── modules/ +│ │ └── mod_example/ +│ └── plugins/ +│ └── system/ +│ └── example/ +├── tests/ +├── docs/ +├── changelog.xml +├── composer.json +├── jorobo.ini +├── jorobo.dist.ini +└── RoboFile.php +``` + +This layout allows JoRobo to copy or symlink the contents of `src/` directly into a Joomla installation without any additional path mapping. The `dist/` folder (generated automatically) holds the finished zip packages and is safe to add to `.gitignore`. + +## Configuration: jorobo.ini + +All project-specific settings live in `jorobo.ini`. The file uses standard INI syntax and is divided into four sections. + +### Main section + +```ini +; The name of the extension (e.g. com_example, mod_example, plg_system_example) +extension = + +; The version that is used for building and releasing +version = + +; The folder that contains the extension source code +source = src + +; Which deployment targets to run with "vendor/bin/robo build" +; Possible values: package, release, ftp (space-separated) +target = package +``` + +The `target` setting controls what happens when you run `vendor/bin/robo build`: + +| Value | Effect | +| --------- | ----------------------------------------- | +| `package` | Creates an installable zip in `/dist` | +| `release` | Publishes the package as a GitHub release | +| `ftp` | Uploads the package to an FTP server | + +You can combine multiple targets: `target = package release`. + +### GitHub section + +```ini +[github] +; The git remote to push tags and changelog commits to +remote = origin + +; The branch from which releases are created +branch = main + +; A GitHub personal access token with "repo" scope +token = + +; The GitHub account or organisation that owns the repository +owner = your-github-username + +; The name of the GitHub repository +repository = your-repo-name + +; Where to get changelog entries from: "commits" or "pulls" +changelog_source = commits +``` + +Generate a personal access token at GitHub → Settings → Developer Settings → Personal access tokens. The token needs at least the `repo` scope. + +### FTP section + +```ini +[ftp] +host = +port = 21 +user = +password = +ssl = false + +; The target directory on the server +target = / +``` + +### Header section + +``` +[header] +; File extensions to add/update headers in +files = php,js,xml + +; Comma-separated list of folders to exclude +exclude = + +; The copyright header text; ##YEAR## is replaced automatically +text = " +/** + * @package Example + * + * @copyright Copyright (C) 2020 - ##YEAR## Your Name. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ +" +``` + +## RoboFile.php + +Your repository needs a `RoboFile.php` that pulls in the JoRobo tasks. The minimal version looks like this: + +```php +-.zip` (or `pkg--.zip` for package extensions) and is placed in the `dist/` folder. + +### map — symlink into a Joomla installation + +```bash +vendor/bin/robo map /path/to/joomla +``` + +Instead of copying files, `map` creates symlinks from your local Joomla installation back into the `src/` folder of your repository. This means you can edit files in your repo and immediately see the changes in your Joomla installation without any manual file copying. + +:::note +On Windows, creating symlinks requires administrator privileges or Developer Mode to be enabled. +::: + +### bump — update version placeholders + +```bash +vendor/bin/robo bump +``` + +Replaces the string `__DEPLOY_VERSION__` in every file inside `src/` with the version set in `jorobo.ini`. Use this before tagging a release to make sure all files (manifests, PHP constants, JavaScript) carry the correct version number. + +A typical workflow is: + +1. Update `version =` in `jorobo.ini`. +2. Run `vendor/bin/robo bump` to propagate the version into all source files. +3. Commit the changes. +4. Run `vendor/bin/robo build` to create the package. + +### headers — update copyright headers + +```bash +vendor/bin/robo headers +``` + +Reads the `[header]` section of `jorobo.ini` and adds or replaces the copyright block at the top of every matching file in `src/`. `##YEAR##` in the header text is automatically replaced with the current year. + +### changelog — generate changelog.xml + +```bash +vendor/bin/robo changelog +``` + +Inspects your git history since the most recent tag and prepends a new `` block to `changelog.xml` in the repository root. The file follows the [Joomla changelog XML format](https://docs.joomla.org/Changelog) and can be referenced directly from your extension manifest. + +JoRobo detects change types automatically based on conventional commit prefixes: + +| Commit prefix | Type in changelog | +| ------------------- | ----------------- | +| `fix:`, `bug:` | Bug Fix | +| `feat:`, `feature:` | Feature | +| `security:` | Security Fix | +| `lang:` | Language fix | +| Anything else | Note | + +### assetJSON — generate joomla.asset.json + +```bash +vendor/bin/robo assetJSON +``` + +Generates a `joomla.asset.json` file for your extension. This file is required by the Joomla Web Asset Manager (introduced in Joomla 4) to declare JavaScript and CSS assets. + +### minify — minify CSS and JavaScript + +```bash +vendor/bin/robo minify +``` + +Minifies all CSS and JavaScript files in the given path relative to `src/`. + + +## Publishing a release to GitHub + +JoRobo can create a full GitHub release — including the changelog, a git tag, and the package upload — in a single command. + +### 1. Configure jorobo.ini + +Fill in the `[github]` section and add `release` to the `target` list: + +```ini +extension = com_example +version = 1.2.0 +source = src +target = package release + +[github] +remote = origin +branch = main +token = ghp_YOUR_PERSONAL_ACCESS_TOKEN +owner = your-github-username +repository = com_example +changelog_source = commits +``` + +### 2. Prepare the release + +```bash +# Update version in all source files +vendor/bin/robo bump + +# Optionally update copyright years +vendor/bin/robo headers + +# Review and commit all changes +git add -A +git commit -m "Prepare release 1.2.0" +git push +``` + +### 3. Build and release + +```bash +vendor/bin/robo build +``` + +When `target` contains `release`, JoRobo will: + +1. Collect all commits (or merged pull requests, depending on `changelog_source`) since the last GitHub release. +2. Append a new entry to `changelog.xml`. +3. Commit the updated changelog to the configured branch and push it. +4. Create an annotated git tag with the version number and push it. +5. Create a GitHub release with the changelog as the release description. +6. Upload the zip package from `dist/` as a release asset. + +After the command completes, the release is live at `https://github.com///releases`. + +## Publishing a release to an FTP server + +For distributing packages via FTP instead of (or in addition to) GitHub, configure the `[ftp]` section and add `ftp` to `target`: + +```ini +target = package ftp + +[ftp] +host = ftp.example.com +port = 21 +user = ftpuser +password = secret +ssl = false +target = /public_html/downloads +``` + +Running `vendor/bin/robo build` will first build the zip package and then upload it to the specified directory on the FTP server. SSL connections are supported by setting `ssl = true`. + +## Integrating JoRobo into CI/CD + +JoRobo runs from the command line, so it fits naturally into any CI pipeline (GitHub Actions, GitLab CI, Drone, etc.). A minimal GitHub Actions workflow for building and releasing looks like this: + +```yaml +name: Release + +on: + push: + tags: + - 'v*' + +jobs: + release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Install dependencies + run: composer install --no-dev + + - name: Create jorobo.ini from template + run: | + cp jorobo.dist.ini jorobo.ini + sed -i "s/^token =$/token = ${{ secrets.GITHUB_TOKEN }}/" jorobo.ini + + - name: Build and release + run: vendor/bin/robo build +``` + +Store your GitHub token as an Actions secret and inject it into `jorobo.ini` at runtime so it is never committed to the repository. + +## Typical local development workflow + +```bash +# 1. Clone your repo and install dependencies +git clone https://github.com/you/com_example.git +cd com_example +composer install + +# 2. Symlink into your local Joomla installation +vendor/bin/robo map /var/www/html/joomla + +# 3. Work on your code in src/ ... + +# 4. Before releasing: bump version, update headers, build package +vendor/bin/robo bump +vendor/bin/robo headers +vendor/bin/robo build + +# 5. The installable zip is now in dist/ +ls dist/ +```