Deploy to Square Cloud from GitHub Actions
On every push, release or manual run, the official action installs the Square Cloud CLI on the runner, checks it and sends your code to your application.
Deploy on every push in three steps
Two values saved in your repository and one workflow file. From then on, each push to main sends the code to your application and restarts it.
- 1
Save an API key as a secret
Create an API key in your account's security settings and save it in the repository as the secret SQUARECLOUD_API_KEY.
- 2
Save the application ID
Copy the ID from the application's page in the dashboard and save it as the repository variable SQUARECLOUD_APP_ID.
- 3
Add the workflow
Commit the file below as .github/workflows/deploy.yml. The next push to main deploys your application.
name: Deployon: push: branches: [main]jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 - uses: squarecloudofc/github-action@v2 with: token: ${{ secrets.SQUARECLOUD_API_KEY }} command: commit ${{ vars.SQUARECLOUD_APP_ID }} --restartKeep the checkout step
Without
actions/checkout, the runner has no files to send.Stopped? It starts too
--restartrestarts the application after the upload and starts it if it was stopped. Without it, the new files take effect on the next restart.The ID can live in the folder
Without an ID,
commitreads theID=line of thesquarecloud.appin the folder, when there is one, socommit --restartis enough.
What the action does on the runner
Four steps, in this order, on every runner. If any of them fails, the step fails too, so a deploy that didn't happen never shows up green.
- 1
Downloads the build for the runner
It picks the CLI release for the runner's system and processor: the latest one, or the version you pin. Self-hosted runners keep it in their tool cache.
- 2
Checks it before installing
The download's SHA-256 is compared with the release's
checksums.txt. A file that doesn't match is never installed or run. - 3
Passes the key without saving it
The key is masked in the logs and set as
SQUARECLOUD_API_KEYfor the rest of the job. Nothing is written to the runner's disk. - 4
Runs your command
squarecloudfollowed by yourcommandruns inworkdir. If the command fails, the step fails.
A workflow for each way you ship
Four patterns from the action's documentation, ready to copy. The highlighted lines are what changes from the workflow above.
Staging and production
Pushes to
maingo to production and pushes todevelopgo to staging, each to its own application.- The Run workflow button in the Actions tab deploys the branch you pick
concurrencymakes deploys of the same branch wait for each other instead of overlapping
.github/workflows/deploy.ymlname: Deployon: push: branches: [main, develop] workflow_dispatch:concurrency: group: deploy-${{ github.ref_name }}jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 - uses: squarecloudofc/github-action@v2 with: token: ${{ secrets.SQUARECLOUD_API_KEY }} command: commit ${{ github.ref_name == 'main' && vars.PRODUCTION_APP_ID || vars.STAGING_APP_ID }} --restartSeveral applications in one repository
Each folder is its own application. A matrix deploys them side by side, one job per folder.
workdirpoints each deploy at its folderfail-fast: falsekeeps one failed deploy from cancelling the others
.github/workflows/deploy.ymlname: Deployon: push: branches: [main]jobs: deploy: runs-on: ubuntu-latest strategy: fail-fast: false matrix: include: - folder: bot app: ${{ vars.BOT_APP_ID }} - folder: website app: ${{ vars.WEBSITE_APP_ID }} steps: - uses: actions/checkout@v7 - uses: squarecloudofc/github-action@v2 with: token: ${{ secrets.SQUARECLOUD_API_KEY }} workdir: ${{ matrix.folder }} command: commit ${{ matrix.app }} --restartDeploy when a release is published
Only the code of a published release reaches the application.
- Pushes and draft releases don't deploy
.github/workflows/deploy.ymlname: Deployon: release: types: [published]jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 - uses: squarecloudofc/github-action@v2 with: token: ${{ secrets.SQUARECLOUD_API_KEY }} command: commit ${{ vars.SQUARECLOUD_APP_ID }} --restartEnvironment variables from secrets
Keep tokens and passwords in GitHub secrets and send them to the application before each deploy.
env setadds or updates only the variables it lists, and the restart after the commit loads them.- From CLI 3.1.1 on, values with spaces or characters such as
$,&,;or|arrive exactly as stored in the secret - On CLI 3.1.0, wrap each value in single quotes yourself
- Passing secrets through
envkeeps their values out of the script GitHub runs
jobs.deploy.steps- uses: squarecloudofc/github-action@v2 with: token: ${{ secrets.SQUARECLOUD_API_KEY }} install-only: true- name: Update environment variables run: squarecloud app env set --app "$APP_ID" "DISCORD_TOKEN=$DISCORD_TOKEN" "DATABASE_URL=$DATABASE_URL" env: APP_ID: ${{ vars.SQUARECLOUD_APP_ID }} DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }} DATABASE_URL: ${{ secrets.DATABASE_URL }}- run: squarecloud commit ${{ vars.SQUARECLOUD_APP_ID }} --restart- From CLI 3.1.1 on, values with spaces or characters such as
Five inputs
Only token is required. The others have defaults you can leave alone.
tokenRequired- Your Square Cloud API key. Keep it in a secret, never in the workflow file.
command- The CLI command to run, without the
squarecloudprefix, such ascommit --restart. Without it, the action only installs the CLI. versionDefaultlatest- The CLI version to install:
latest, or 3.1.0 or later. Finding the latest version doesn't call the GitHub API, so its rate limit never gets in the way. workdirDefault.- The folder the command runs in, relative to the repository root.
install-onlyDefaultfalse- Only installs the CLI and sets the key, so later steps of the job can run
squarecloudthemselves.
Pin the CLI version
Deploys the bot folder with CLI 3.1.1 on every run, whatever the latest release is.
jobs.deploy.steps- uses: squarecloudofc/github-action@v2 with: token: ${{ secrets.SQUARECLOUD_API_KEY }} version: 3.1.1 workdir: bot command: commit ${{ vars.SQUARECLOUD_APP_ID }} --restartRun several commands
With install-only, the CLI and its key stay available to the next steps: build, deploy, then read the status as JSON.
jobs.deploy.steps- uses: squarecloudofc/github-action@v2 with: token: ${{ secrets.SQUARECLOUD_API_KEY }} install-only: true- run: npm ci && npm run build- run: squarecloud commit ${{ vars.SQUARECLOUD_APP_ID }} --restart- run: squarecloud app status ${{ vars.SQUARECLOUD_APP_ID }} --json
Any GitHub runner
The action is tested on GitHub's Linux, Windows and macOS runners, on x64 and arm64. Your own self-hosted runners work too, as long as their runner version supports node24 actions.
Linux
x64 and arm64 on GitHub-hosted runners. Your own runners can also be x86 or ARMv7.
- Tested on ubuntu-latest and ubuntu-24.04-arm
Windows
x64 and arm64 on GitHub-hosted runners. Your own runners can also be x86.
- Tested on windows-latest and windows-11-arm
macOS
Intel and Apple silicon, on GitHub-hosted runners and on your own.
- Tested on macos-latest
Your key stays a secret
The action handles the API key like the password it is.
Masked in the logs
The key is registered as a secret before anything runs, so it prints as *** in every log line.
Never on disk
The CLI reads it from SQUARECLOUD_API_KEY. It isn't saved on the runner or passed on the command line.
Scoped to one job
Later steps of the same job can use it; other jobs can't. Run actions you don't trust in a separate job.
One key per repository
Give each repository its own key, so you can revoke one without touching the others.
A CLI made for workflows
Every command the action runs is a Square Cloud CLI command, and the CLI is built to work without a terminal.
Confirm with -y
Commands that change or delete data ask first. A workflow can't answer, so add
-y: without it, the command exits with code 1 and changes nothing.JSON for scripts
Commands that print data accept
--json, for output the next step can parse.Trace every request
Set
SQUARECLOUD_DEBUG: 1in the step'senvto log each API request's method, path, status and duration, never headers or bodies.Choose what's sent
commitleaves out whatsquarecloud.ignorelists, in gitignore syntax.node_modules,.gitand lockfiles stay out unless you add them back with!.
Already using @v2?
@v2 now points to the new version, so your workflow keeps working unchanged. Here is what changed.
workdiris applied. Up to 2.1.2 it was ignored and commands ran in the repository root.- The key is no longer passed on the command line or saved on the runner.
- Windows, macOS and arm64 runners are supported.
- The CLI download is checked against its checksums, and the new
versioninput pins it. - Finding the latest CLI no longer calls the GitHub API, so the API rate limit doesn't affect it.
- The action runs on Node 24.
CLI 3.1 also leaves lockfiles out of uploads. To keep sending yours, add !package-lock.json (or your lockfile) to squarecloud.ignore.
A plan for every stage of your project
Start small and scale when you need to, with no loyalty contracts.
Hobby
To validate ideas, bots and personal projects
From R$12.49/mo ≈ $2.25
- 1 GB RAM
- 1 vCPU
- Up to 4 projects
- Scales up to 2 GB on the same plan
Standard
RecommendedFor production, with databases and custom domains
From R$44.99/mo ≈ $8.10
- 4 GB RAM
- 4 vCPU
- Up to 16 projects
- Scales up to 8 GB on the same plan
Pro
For high scale, with daily application snapshots and advanced analytics
From R$124.99/mo ≈ $22.50
- 12 GB RAM
- 6 vCPU
- Up to 48 projects
- Scales up to 24 GB on the same plan
4.9 out of 5 · 402 reviews on Google + TrustpilotTrustpilot