{"id":48986813,"url":"https://github.com/dix/publish-to-o2switch","last_synced_at":"2026-05-01T11:01:30.202Z","repository":{"id":352188052,"uuid":"1214188898","full_name":"dix/publish-to-o2switch","owner":"dix","description":"All-in-one action to publish content to o2switch 🐯","archived":false,"fork":false,"pushed_at":"2026-04-18T11:37:49.000Z","size":34,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-18T13:28:40.082Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dix.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-18T08:26:36.000Z","updated_at":"2026-04-18T11:36:34.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/dix/publish-to-o2switch","commit_stats":null,"previous_names":["dix/publish-to-o2switch"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/dix/publish-to-o2switch","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dix%2Fpublish-to-o2switch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dix%2Fpublish-to-o2switch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dix%2Fpublish-to-o2switch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dix%2Fpublish-to-o2switch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dix","download_url":"https://codeload.github.com/dix/publish-to-o2switch/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dix%2Fpublish-to-o2switch/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32494275,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-30T13:12:12.517Z","status":"online","status_checked_at":"2026-05-01T02:00:05.856Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-18T13:05:28.705Z","updated_at":"2026-05-01T11:01:30.187Z","avatar_url":"https://github.com/dix.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# ⬆️ publish-to-o2switch 🐯\n\nAll-in-one action to publish content to o2switch 🐯, managing IP whitelisting, archiving, releases, exclusions...\n\nAlso tested and validated on [Gitea](https://docs.gitea.com/usage/actions/ \"Gitea\") 🍵.\n\n## Quickstart example\n\n```yaml\nname: publish-to-o2switch quickstart\n\non:\n  push:\n    branches: [ main ]\n\njobs:\n  build-deploy:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v6\n\n      # Custom steps...\n      - name: Build\n        run: npm ci \u0026\u0026 npm run build\n\n      # Publishing with the action\n      - name: Publish to o2switch\n        uses: dix/publish-to-o2switch@v1.1\n        with:\n          o2switch_host: ${{ secrets.O2SWITCH_HOST }}\n          o2switch_username: ${{ secrets.O2SWITCH_USER }}\n          o2switch_api_token: ${{ secrets.O2SWITCH_API_TOKEN }}\n          ssh_private_key: ${{ secrets.O2SWITCH_SSH_PRIVATE_KEY }}\n          remote_path: ~/publish-to-o2switch\n          local_path: ./\n          exclude: /node_modules/,/dist/\n```\n\n## Documentation\n\n### Setup\n\nWe need to create the required secrets in the GitHub repository.\n\n- Go to https://github.com/USER/PROJECT/settings/secrets/actions or `Settings -\u003e Secrets and variables -\u003e Actions`\n- On cPanel, retrieve O2Switch host related to subscription by going to Technical Space and extract the DNS from the URL\n  that should looks like `https://xyz.o2switch.net:2083/`; in this case host is `xyz.o2switch.net`. Then create a\n  Repository Secret called `O2SWITCH_HOST` with this value\n- On cPanel, retrieve O2Switch username at the top right under `General Information -\u003e Current User` and create a\n  Repository Secret called `O2SWITCH_USER` with this value\n- On cPanel, get an API Token under `Manage API Tokens` and create a Repository Secret called `O2SWITCH_API_TOKEN` with\n  this value\n- Go through the `SSH key setup` part below\n- For the other inputs, you can hard-code them in the workflow YAML or use variables or secrets\n\n#### SSH key setup\n\nFirst, we recommend creating a dedicated SSH key for the publishing process, to avoid mixing things with actual human\naccess from your computer.\n\n```bash\nssh-keygen -t ed25519 -C \"publish-to-o2switch\" -f \"/REPLACE/LOCAL/PATH/publish-to-o2switch\" -N \"\"\n```\n\nCreate a Repository Secret called `O2SWITCH_SSH_PRIVATE_KEY` with the content of the newly created `publish-to-o2switch`\nfile, don't forget to put a newline at the end:\n\n```text\n-----BEGIN OPENSSH PRIVATE KEY-----\nxyz\n-----END OPENSSH PRIVATE KEY-----\n\n```\n\nTo allow this key, first copy the content of `publish-to-o2switch.pub`, then two options:\n\n- Connect in SSH to the server, then add the public key to the existing ones with\n  `echo \"ssh-ed25519 XYZ... publish-to-o2switch\" \u003e\u003e ~/.ssh/authorized_keys`\n- On cPanel\n    - Go to `SSH Access -\u003e Manage SSH Keys -\u003e Import Key`\n    - Use `publish-to-o2switch` for the `name` field\n    - Paste the content of `publish-to-o2switch.pub` in the `public key` field\n    - Leave `private key` and `passphrase`\n    - Click `Import`\n    - Next click `Back to Manage Keys`\n    - Under `Public Keys` and next to the new `publish-to-o2switch` key, click `Manage`\n    - Finally, click on `Authorize`\n\nNote: it's not clear if this step is doable through the API at the moment, thus the manual actions...\n\n### Inputs\n\n| name                 | details                                          | description                                                                 |\n|----------------------|--------------------------------------------------|-----------------------------------------------------------------------------|\n| `o2switch_host`      | **required**                                     | O2Switch host, e.g. `tigers.o2switch.net`                                   |\n| `o2switch_username`  | **required**                                     | cPanel username                                                             |\n| `o2switch_api_token` | **required**                                     | cPanel API token                                                            |\n| `ssh_user`           | optional (defaults to `o2switch_username`)       | SSH username                                                                |\n| `ssh_private_key`    | **required**                                     | SSH private key                                                             |\n| `remote_path`        | **required**                                     | Remote path to deploy to (can be /home/USERNAME/xxx or ./xxx or ~/xxx       |\n| `local_path`         | optional (default `./`)                          | Local path to deploy from                                                   |\n| `ssh_port`           | optional (default `22`)                          | SSH port                                                                    |\n| `rsync_args`         | optional (default `-rlgoDzvc -i --delete-after`) | rsync flags                                                                 |\n| `exclude`            | optional                                         | Comma-separated list of publishing exclusions, e.g. `/dist/,/node_modules/` |\n| `use_archive`        | optional (default `false`)                       | Use a tar.gz archive instead of rsync                                       |\n| `use_releases`       | optional (default `false`)                       | Deploy to release directories and update a symlink                          |\n| `releases_dir`       | optional (required if `use_releases=true`)       | Remote releases directory (only for `use_releases`)                         |\n| `current_link`       | optional (required if `use_releases=true`)       | Remote symlink path for the current release (only for `use_releases`)       |\n| `keep_releases`      | optional (default `3`)                           | Number of releases to keep (only for `use_releases`)                        |\n| `skip_cleanup_whitelist` | optional (default `false`)                   | Skip the cleanup whitelist step                                              |\n\n### Modes\n\nThe action support two modes: `default` and `releases`.\n\nManaged with input `use_releases`.\n\n#### default\n\nSimply replace the existing content on the remote server by the new one.\n\n#### releases\n\nCreates a new subdirectory to publish content, updates symlink to point to new release and remove old releases.\n\nThe goal is to have multiple releases available on the remote server to easily switch/rollback between them.\n\nExample:\n\n1. Create `/home/USERNAME/tigers` directory on the remote server.\n2. On cPanel, declare subdomain `tigers.mi5.com` to have its root at `tigers/current`.\n3. Use the action with options `use_releases: true`, `releases_dir: \"~/tigers/releases\"` and\n   `current_link: \"~/tigers/current\"`\n4. The action will create a new release subdirectory in `/home/USERNAME/tigers/releases/xyz` and once published, will\n   create/update a symlink on `/home/USERNAME/tigers/current` pointing to `/home/USERNAME/tigers/releases/xyz`\n5. Subdomain `tigers.mi5.com` will then serve content of the new release\n6. Rolling-back to an older release can be achieved simply by updating the symlink to make it point to an older release\n   subdirectory\n\n### Archiving\n\nDepending on the number of files to publish, creating a local archive of the files, uploading it to the server and\nextracting it there can provide much better performances than dealing with each file one-by-one.\n\nThe input `use_archive` is here to activate this option.\n\nUsage greatly recommended in `releases` mode, since all files are uploaded in the new release directory.\nIn `default` mode, it's debatable. The use of `rsync` limits uploads to only the modified files, but a check is required\nfor each file, which can take quite some time if the number of files is in the hundreds or more.\n\n### Whitelisting\n\nBy default, SSH access is blocked by o2switch, so we first need to allow the GitHub runner's random public IP through cPanel\nAPI.\n\nSince the number of authorized IPs is limited, we always delete the IP in the end, even if the deployment failed,\navoiding leaving a mess in your account.\n\nFor self-hosted runners, particularly for Gitea, use `skip_cleanup_whitelist: true` to skip this step and keep the IP whitelisted.\n\n### Exclusions\n\nThe `exclude` input provides with the option to exclude files and directories, through a comma separated list, from the\ndeployment.\nSupported for rsync/archiving and all modes.\n\n## Notes\n\n- Greatly inspired by the work of webaxones and friends\n  in [this Gist](https://gist.github.com/webaxones/54a9aee13bd9152e900ef30a0fcef3ed \"GitHub\").\n- This project is not affiliated with or endorsed by [O2Switch](https://www.o2switch.fr/ \"o2switch\") 🐯.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdix%2Fpublish-to-o2switch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdix%2Fpublish-to-o2switch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdix%2Fpublish-to-o2switch/lists"}