Repository: 8398a7/action-slack (ts)

Issue:
Auto detect the job in reusable workflow
**Is your feature request related to a problem? Please describe.**
In reusable workflow, action-slack cannot find job from [job list of current run](https://github.com/8398a7/action-slack/blob/v3.12.0/src/fields.ts#L141-L145). So field `job` and `took` are not available.

![image](https://user-images.githubusercontent.com/7571111/148557364-2e74f0ae-9622-467c-a66b-124b4e5ab892.png)

<details>
<summary>Example workflow</summary>

Reusable workflow
```yaml
# reusable workflow
name: shared-greet-and-notify
on:
  workflow_call:
    secrets:
      SLACK_WEBHOOK_URL
jobs:
  greet-and-notify:
    runs-on: ubuntu-latest
    steps:
      - name: greet
        run: echo hello
      - name: notify
        uses: 8398a7/action-slack@v3
        with:
          status: ${{ job.status }}
          fields: repo,took,workflow,job,ref,message
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
        if: always()
```

Actual workflow
```yaml
# using the reusable workflow
name: call-reusable
on: [push]
jobs:
  greeting:
    uses: owner/repo/.github/workflows/shared-greet-and-notify.yml@main
    secrets:
      SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
```
</details>

In reusable workflow's job, `github.job` is the job name defined in the reusable workflow. But the format of job name in API response is `"<caller-job> / <callee-job>"` 
(In abobe example, `github.job` is `"something-and-notify"` and job name in the response is `"greeting / greet-and-notify"`)

**Describe the solution you'd like**
I want the job to be detected in the same way as a normal workflow.
IMO, most common cases can be resolved by checking if the job name in response ends with `" / <callee-job>"`.
```diff
-    const currentJob = resp?.data.jobs.find(job => job.name === this.jobName);
+    const currentJob = resp?.data.jobs.find(job => job.name === this.jobName || job.name.endsWith(` / ${this.jobName}`));
```
This will be wrong when workflow uses multiple reusable workflow AND job names are duplicated. But I think that it seems rare case.
If this seems good, I'll create PR.

**Describe alternatives you've considered**
There are available by passing caller's job name via `inputs` and setting `job_name`. but it is very redundancy.

<details>
<summary>Example</summary>

```yaml
name: shared-greet-and-notify
on:
  workflow_call:
    inputs:
      caller:
        type: string
        required: true
    secrets:
      SLACK_WEBHOOK_URL
jobs:
  greet-and-notify:
    runs-on: ubuntu-latest
    steps:
      - name: greet
        run: echo hello
      - name: notify
        uses: 8398a7/action-slack@v3
        with:
          status: ${{ job.status }}
          fields: repo,took,workflow,job,ref,message
          job_name: ${{ inputs.caller }} / greet-and-notify
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
        if: always()
```

```yaml
name: call-reusable
on: [push]
jobs:
  greeting:
    uses: owner/repo/.github/workflows/shared-greet-and-notify.yml@main
    with:
      caller: greeting # unfortunately, cannot using ${{ github.job }} in here
    secrets:
      SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
```
</details>

**Additional context**
N/A


Pull request description:
Check reusable workflow's job name pattern
Close #183.

This PR changes job detection for `job` and `took` in `FieldFactory`.
In addition to the original exact match, It also checks if the job name matches with the pattern of reusable workflow's job name (`*** / ${this.jobName}`).

Patch:
diff --git a/src/fields.ts b/src/fields.ts
index d6bbdc6..3712388 100644
--- a/src/fields.ts
+++ b/src/fields.ts
@@ -108,7 +108,9 @@ export class FieldFactory {
       repo: context.repo.repo,
       run_id: context.runId,
     });
-    const currentJob = resp?.data.jobs.find(job => job.name === this.jobName);
+    const currentJob = resp?.data.jobs.find(job =>
+      this.isCurrentJobName(job.name),
+    );
     if (currentJob === undefined) {
       process.env.AS_TOOK = this.jobIsNotFound;
       return this.jobIsNotFound;
@@ -143,7 +145,9 @@ export class FieldFactory {
       repo: context.repo.repo,
       run_id: context.runId,
     });
-    const currentJob = resp?.data.jobs.find(job => job.name === this.jobName);
+    const currentJob = resp?.data.jobs.find(job =>
+      this.isCurrentJobName(job.name),
+    );
     if (currentJob === undefined) {
       process.env.AS_JOB = this.jobIsNotFound;
       return this.jobIsNotFound;
@@ -227,6 +231,10 @@ export class FieldFactory {
     return await octokit.rest.repos.getCommit({ owner, repo, ref });
   }
 
+  private isCurrentJobName(name: string): boolean {
+    return name === this.jobName || name.endsWith(` / ${this.jobName}`);
+  }
+
   private get jobIsNotFound() {
     return 'Job is not found.\nCheck <https://action-slack.netlify.app/fields|the matrix> or <https://action-slack.netlify.app/with#job_name|job name>.';
   }


Test patch:
diff --git a/__tests__/fixtures/actions.reusable-workflow-job-name.jobs.json b/__tests__/fixtures/actions.reusable-workflow-job-name.jobs.json
new file mode 100644
index 0000000..611f04e
--- /dev/null
+++ b/__tests__/fixtures/actions.reusable-workflow-job-name.jobs.json
@@ -0,0 +1,30 @@
+{
+  "total_count": 1,
+  "jobs": [
+    {
+      "id": 762195612,
+      "run_id": 132308092,
+      "run_url": "https://api.github.com/repos/8398a7/action-slack/actions/runs/132308092",
+      "node_id": "MDg6Q2hlY2tSdW43NjIxOTU2MTI=",
+      "head_sha": "cd15a66fc57d465564195faeb5308a63b4317cde",
+      "url": "https://api.github.com/repos/8398a7/action-slack/actions/jobs/762195612",
+      "html_url": "https://github.com/8398a7/action-slack/runs/762195612",
+      "status": "in_progress",
+      "conclusion": null,
+      "started_at": "2020-06-11T15:05:49Z",
+      "completed_at": null,
+      "name": "call-reusable / notification",
+      "steps": [
+        {
+          "name": "Set up job",
+          "status": "in_progress",
+          "conclusion": null,
+          "number": 1,
+          "started_at": "2020-06-11T15:05:49.000Z",
+          "completed_at": null
+        }
+      ],
+      "check_run_url": "https://api.github.com/repos/8398a7/action-slack/check-runs/762195612"
+    }
+  ]
+}
diff --git a/__tests__/reusableWorkflowJobName.test.ts b/__tests__/reusableWorkflowJobName.test.ts
new file mode 100644
index 0000000..24b513c
--- /dev/null
+++ b/__tests__/reusableWorkflowJobName.test.ts
@@ -0,0 +1,72 @@
+import nock from 'nock';
+
+process.env.GITHUB_RUN_ID = '2';
+
+import {
+  gitHubToken,
+  gitHubBaseUrl,
+  newWith,
+  setupNockCommit,
+  setupNockJobs,
+  successMsg,
+  webhookUrl,
+} from './helper';
+import { Client, With, Success } from '../src/client';
+
+beforeAll(() => {
+  nock.disableNetConnect();
+  setupNockCommit(process.env.GITHUB_SHA as string);
+  setupNockJobs(
+    process.env.GITHUB_RUN_ID as string,
+    'actions.reusable-workflow-job-name.jobs',
+  );
+});
+afterAll(() => {
+  nock.cleanAll();
+  nock.enableNetConnect();
+});
+
+describe('job_name', () => {
+  beforeEach(() => {
+    process.env.GITHUB_REPOSITORY = '8398a7/action-slack';
+    process.env.GITHUB_EVENT_NAME = 'push';
+    const github = require('@actions/github');
+    github.context.payload = {};
+  });
+
+  it('works even if the job is in reusable workflow', async () => {
+    const withParams: With = {
+      ...newWith(),
+      status: Success,
+      fields: 'job,took',
+    };
+    const client = new Client(
+      withParams,
+      gitHubToken,
+      gitHubBaseUrl,
+      webhookUrl,
+    );
+    expect(await client.prepare('')).toStrictEqual({
+      text: successMsg,
+      attachments: [
+        {
+          author_name: '',
+          color: 'good',
+          fields: [
+            {
+              short: true,
+              title: 'job',
+              value:
+                '<https://github.com/8398a7/action-slack/runs/762195612|notification>',
+            },
+            { short: true, title: 'took', value: '1 hour 1 min 1 sec' },
+          ],
+        },
+      ],
+      username: '',
+      icon_emoji: '',
+      icon_url: '',
+      channel: '',
+    });
+  });
+});