{"id":50529931,"url":"https://github.com/nullstone-io/gh-actions","last_synced_at":"2026-06-03T12:30:21.585Z","repository":{"id":357463467,"uuid":"1233400168","full_name":"nullstone-io/gh-actions","owner":"nullstone-io","description":"Catalog of GitHub Actions for managing apps and infrastructure through Nullstone","archived":false,"fork":false,"pushed_at":"2026-05-12T21:26:34.000Z","size":13,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-05-12T23:26:26.147Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/nullstone-io.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-05-08T23:20:00.000Z","updated_at":"2026-05-12T21:26:25.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/nullstone-io/gh-actions","commit_stats":null,"previous_names":["nullstone-io/gh-actions"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/nullstone-io/gh-actions","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nullstone-io%2Fgh-actions","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nullstone-io%2Fgh-actions/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nullstone-io%2Fgh-actions/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nullstone-io%2Fgh-actions/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nullstone-io","download_url":"https://codeload.github.com/nullstone-io/gh-actions/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nullstone-io%2Fgh-actions/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33865655,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-03T02:00:06.370Z","response_time":59,"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-06-03T12:30:18.995Z","updated_at":"2026-06-03T12:30:21.577Z","avatar_url":"https://github.com/nullstone-io.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# gh-actions\n\nCatalog of reusable composite GitHub Actions for assembling a Nullstone deploy pipeline. Each subdirectory is its own action — reference it by path-qualified `uses:` URL.\n\n## Actions\n\n| Action | Purpose |\n| -- | -- |\n| [`publish-module`](publish-module/) | Publish a Nullstone IaC module if its source files changed in the most recent commit (exposes `changed` output) |\n| [`build-publish-docker-app`](build-publish-docker-app/) | Build a single app's container image with Buildx and push it to the Nullstone artifact registry |\n| [`build-deploy-docker-app`](build-deploy-docker-app/) | Build, publish, and deploy a single app's container image in one step |\n| [`build-release-docker-app`](build-release-docker-app/) | Build, publish, and release (infra-update + deploy) a single app's container image in one step |\n| [`iac-sync`](iac-sync/) | Run `nullstone iac-sync` for a target environment |\n| [`iac-test`](iac-test/) | Run `nullstone iac test` against a target environment (typically on pull requests) |\n| [`deploy-and-run`](deploy-and-run/) | Deploy a Nullstone app and execute a follow-up command (migrations, seeds, batch jobs) |\n| [`deploy-app`](deploy-app/) | Deploy a single Nullstone app via `nullstone deploy` |\n| [`release-app`](release-app/) | Release a single Nullstone app (infra-update + deploy) via `nullstone release` |\n\n## Consumer convention\n\nEach action reads Nullstone credentials from the environment. Surface them once at the workflow (or job) level — the per-call YAML never has to mention them:\n\n```yaml\nenv:\n  NULLSTONE_ORG: ${{ vars.NULLSTONE_ORG }}\n  NULLSTONE_STACK: ${{ vars.NULLSTONE_STACK }}\n  NULLSTONE_API_KEY: ${{ secrets.NULLSTONE_API_KEY }}\n```\n\n`secrets` context is not available inside a composite action, so this `env:` block is required wherever these actions are used.\n\n## End-to-end example\n\n```yaml\nname: Deploy Taco\n\non:\n  workflow_call:\n    inputs:\n      env:\n        type: string\n        required: true\n      ui-build-args:\n        type: string\n        required: true\n\nenv:\n  NULLSTONE_ORG: ${{ vars.NULLSTONE_ORG }}\n  NULLSTONE_STACK: ${{ vars.NULLSTONE_STACK }}\n  NULLSTONE_API_KEY: ${{ secrets.NULLSTONE_API_KEY }}\n\njobs:\n  publish-modules:\n    runs-on: ubuntu-latest\n    strategy:\n      fail-fast: false\n      matrix:\n        dir:\n          - workflows/order-router\n          - workflows/inventory-sync\n    steps:\n      - uses: nullstone-io/gh-actions/publish-module@v1\n        with:\n          dir: ${{ matrix.dir }}\n\n  publish:\n    runs-on: ubuntu-latest\n    strategy:\n      fail-fast: false\n      matrix:\n        include:\n          - app: taco-api\n            dockerfile: ./Dockerfile\n          - app: taco-migrations\n            dockerfile: ./migrations.Dockerfile\n          - app: taco-ui\n            dockerfile: ./ui/apps/web/Dockerfile\n            build-args: ${{ inputs.ui-build-args }}\n    steps:\n      - uses: nullstone-io/gh-actions/build-publish-docker-app@v1\n        with:\n          env: ${{ inputs.env }}\n          app: ${{ matrix.app }}\n          dockerfile: ${{ matrix.dockerfile }}\n          build-args: ${{ matrix.build-args }}\n\n  iac-sync:\n    needs: [publish]\n    runs-on: ubuntu-latest\n    steps:\n      - uses: nullstone-io/gh-actions/iac-sync@v1\n        with:\n          env: ${{ inputs.env }}\n\n  db-migrate:\n    needs: [publish, iac-sync]\n    runs-on: ubuntu-latest\n    steps:\n      - uses: nullstone-io/gh-actions/deploy-and-run@v1\n        with:\n          env: ${{ inputs.env }}\n          app: taco-migrations\n          command: migrate up\n\n  deploy:\n    needs: [publish, db-migrate]\n    runs-on: ubuntu-latest\n    strategy:\n      fail-fast: false\n      matrix:\n        app:\n          - taco-ui\n          - taco-api\n    steps:\n      - uses: nullstone-io/gh-actions/deploy-app@v1\n        with:\n          env: ${{ inputs.env }}\n          app: ${{ matrix.app }}\n```\n\n## Versioning\n\nTags are monorepo-wide — `v1.0.0` covers every action at the moment that tag points to. Most consumers should pin to the moving major (`@v1`); security-sensitive consumers can pin to a SHA (`@\u003csha\u003e`). Breaking changes in any action bump the major for all of them.\n\nDevelopment happens on the `release/v1` branch; releases are tagged as `v1.x.y` from there and the `v1` tag is force-moved to the latest compatible release.\n\n## Why composite actions, not reusable workflows\n\n- Native `strategy.matrix` and `if:` at the call site, with no JSON-encoded list inputs.\n- Shorter `uses:` URLs.\n\nThe cost (declaring `runs-on:` + `steps:` and surfacing secrets via an `env:` block instead of `secrets: inherit`) is paid once per consumer workflow, not once per call site.\n\n## Marketplace\n\nSubdirectory composite actions are not eligible for the GitHub Marketplace — only repo-root `action.yml` files are. Consumers reference each action by its path-qualified `uses:` URL. The `branding` fields in each `action.yml` are kept as no-ops in case we ever pivot to per-action repos.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnullstone-io%2Fgh-actions","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnullstone-io%2Fgh-actions","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnullstone-io%2Fgh-actions/lists"}