{"id":51322903,"url":"https://github.com/ipeterov/slack-notify-action","last_synced_at":"2026-07-01T15:30:36.799Z","repository":{"id":365713474,"uuid":"1273401701","full_name":"ipeterov/slack-notify-action","owner":"ipeterov","description":null,"archived":false,"fork":false,"pushed_at":"2026-06-18T15:17:27.000Z","size":2388,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-18T15:29:49.750Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","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/ipeterov.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-06-18T13:41:50.000Z","updated_at":"2026-06-18T15:18:16.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ipeterov/slack-notify-action","commit_stats":null,"previous_names":["ipeterov/slack-notify-action"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/ipeterov/slack-notify-action","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ipeterov%2Fslack-notify-action","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ipeterov%2Fslack-notify-action/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ipeterov%2Fslack-notify-action/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ipeterov%2Fslack-notify-action/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ipeterov","download_url":"https://codeload.github.com/ipeterov/slack-notify-action/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ipeterov%2Fslack-notify-action/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35013179,"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-07-01T02:00:05.325Z","response_time":130,"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-07-01T15:30:32.705Z","updated_at":"2026-07-01T15:30:36.794Z","avatar_url":"https://github.com/ipeterov.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# slack-notify-action\n\nA GitHub Action that posts a live-updating Slack card showing the status of jobs\nin the current workflow run.\n\nOne `notify` job runs in parallel with the rest of your pipeline. The action\npolls the GitHub Actions API every few seconds, posts a single Slack message,\nand updates it in place until every watched job reaches a terminal state. You do\n**not** sprinkle notify steps through your pipeline and you do **not** thread a\nmessage id between steps — the action owns the message lifecycle itself.\n\n## Usage\n\nAdd a job to your workflow that runs in parallel with the others:\n\n```yaml\njobs:\n  notify-slack:\n    name: Notify Slack\n    if: github.event_name != 'pull_request'\n    runs-on: ubuntu-latest\n    permissions:\n      actions: read\n      contents: read\n    env:\n      SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}\n    steps:\n      - uses: ipeterov/slack-notify-action@v1\n        with:\n          channel_id: C0123456789\n          jobs: |\n            - linters\n            - tests\n            - build\n            - deploy\n\n  linters:\n    # ...\n  tests:\n    # ...\n  build:\n    # ...\n  deploy:\n    # ...\n```\n\nThe action polls the GitHub Actions API every few seconds and calls\n`chat.update` on a single Slack message until every watched job reaches a\nterminal state.\n\n## Inputs\n\n| Input          | Required | Description |\n|----------------|----------|-------------|\n| `channel_id`   | yes      | Slack channel ID (e.g. `C0123456789`). Channel **names** are not supported — see below. |\n| `jobs`         | yes      | Job ids to watch, in the same form `needs:` accepts. Accepts a scalar, a flow list, or a block list. |\n| `layout`       | no       | `detailed` (default) or `compact`. See [Card layout](#card-layout). |\n| `build_number` | no       | Your own build number for the title (`build #…`). Defaults to GitHub's run number. |\n| `poll_interval`| no       | How often to poll GitHub for updates, in seconds. Minimum `1`, default `5`. |\n| `github-token` | no       | Token to read the run and its jobs. Defaults to `${{ github.token }}`, which only needs `actions: read`. |\n\nThe bot token is read from the **`SLACK_BOT_TOKEN` environment variable**, not an\ninput. Pass it via `env:` on the job (see the example above).\n\nThe `jobs` input takes any of these:\n\n```yaml\njobs: linters\njobs: [linters, tests, deploy]\njobs: |\n  - linters\n  - tests\n  - deploy\n```\n\nJob ids must match the YAML keys under `jobs:` in your workflow file — the same\nstrings you'd use in `needs:`.\n\n## Slack setup\n\nThe action needs a Slack bot token (`xoxb-…`) with the **`chat:write`** scope —\nnothing more. That single scope is a deliberate constraint: resolving a channel\n*name* to an ID would require `channels:read`/`groups:read`, so this action only\naccepts a channel **ID**.\n\nTo find a channel's ID, open the channel in Slack → channel name → **About** →\nthe ID (`C…`) is at the bottom.\n\n### Troubleshooting: invite the bot to the channel\n\nThe most common silent failure is **forgetting to invite the bot to the target\nchannel**. `chat.postMessage` to a channel the bot hasn't joined fails with\n`not_in_channel` even though everything else is configured correctly. In the\nchannel, run:\n\n```\n/invite @your-bot-name\n```\n\nThe action surfaces Slack's `error` field (e.g. `not_in_channel`,\n`channel_not_found`, `invalid_auth`) in the job log, since Slack returns HTTP\n200 even on logical failures.\n\n## Required GitHub permissions\n\nThe notify job needs:\n\n- `actions: read` — to poll the run and its jobs.\n- `contents: read` — to fetch the workflow file and map your `jobs:` ids to the\n  API's display names.\n\nThe default `GITHUB_TOKEN` is sufficient.\n\n## Reruns\n\nThe notify job exits non-zero if any watched job ends in `failure` or\n`timed_out`. This makes \"Re-run failed jobs\" include the notifier alongside the\njobs you're re-running, so the card keeps updating on the new attempt.\n\nEach attempt posts a new Slack message; from attempt 2 onward the title includes\n`(attempt N)` so the cards are easy to tell apart.\n\n## Matrix jobs\n\nMatrix jobs and reusable-workflow jobs are collapsed into one row per job id,\nwith a `N/M done` summary. The card stays compact regardless of how many\ncombinations the matrix expands into.\n\n## Card layout\n\nPick a layout with the `layout` input:\n\n- **`detailed`** (default) — one job per row. For each **in-progress** job the\n  card shows the step it's currently running, and for each **failed** job the\n  step that failed — so you can see what's actually happening or what broke\n  without opening the logs. The job name links to its logs, and a live timer\n  ticks beside running jobs. Best for a handful of jobs.\n- **`compact`** — jobs packed into a dense two-column grid with no step line.\n  Use this when you watch many jobs and don't need per-step detail.\n\n```yaml\nwith:\n  channel_id: C0123456789\n  jobs: [lint, test, deploy]\n  layout: compact\n```\n\nIn both layouts a section's `fields` array caps at 10 entries, so long job\nlists chunk across additional blocks (with a faint gap between them) to keep\nevery job visible.\n\n## Migrating from `ivelum/github-action-slack-notify-build`\n\nThis action is a **zero-setup credential swap** for existing ivelum users:\n\n- **No Slack-admin changes.** Same `SLACK_BOT_TOKEN` secret, same `chat:write`\n  scope. The token is still read from the `SLACK_BOT_TOKEN` environment\n  variable.\n\nWhat changes is the *workflow shape*, not the credentials:\n\n- ivelum's action is a **per-step** notifier — you place N notify steps through\n  your pipeline and thread a `message_id` between them. This action is **one\n  parallel job** that watches `jobs:` and owns the message lifecycle. Replace\n  those N steps with a single `notify-slack` job (see [Usage](#usage)).\n- Provide the channel as a **`channel_id`** (e.g. `C0123456789`), not a channel\n  name. This action requires only `chat:write` and so cannot resolve names.\n- There is no `status`/`color`/`message_id` input — status is discovered from\n  the GitHub API automatically.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fipeterov%2Fslack-notify-action","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fipeterov%2Fslack-notify-action","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fipeterov%2Fslack-notify-action/lists"}