# core/reporters/deployment.reporter.ts

> 79 lines of code and 7 definitions.

Tree: Bane's Lab Deploy
Language: typescript
Layer: operations
Canonical: https://banes-lab.com/anatomy/deploy#file-deploy-core-reporters-deployment-reporter-ts
Source text: https://banes-lab.com/source/deploy/core/reporters/deployment.reporter.ts.txt

Listed in [core/reporters](https://banes-lab.com/api/source/deploy/core/reporters.md), before [core/reporters/journal.reporter.ts](https://banes-lab.com/source/deploy/core/reporters/journal.reporter.ts.md).

## Definitions

- `summaryOf` (lexical_declaration, line 32)
- `reportDeployment` (lexical_declaration, line 62, exported)
- `sharedFields` (lexical_declaration, line 47)
- `monitoringLinks` (lexical_declaration, line 58)
- `files` (lexical_declaration, line 36)
- `size` (lexical_declaration, line 43)
- `fields` (lexical_declaration, line 75, exported)

## Contained in

- [core/reporters](https://banes-lab.com/anatomy/deploy/folder-deploy-core-reporters.md)

## Uses

- [core/converters/markdown.converter.ts](https://banes-lab.com/source/deploy/core/converters/markdown.converter.ts.md)
- [core/probes/system.probe.ts](https://banes-lab.com/source/deploy/core/probes/system.probe.ts.md)
- [core/probes/vcs.probe.ts](https://banes-lab.com/source/deploy/core/probes/vcs.probe.ts.md)
- [core/reporters/notification.reporter.ts](https://banes-lab.com/source/deploy/core/reporters/notification.reporter.ts.md)

## Used by

- [runtime/entrypoints/deployment.entrypoint.ts](https://banes-lab.com/source/deploy/runtime/entrypoints/deployment.entrypoint.ts.md)

## Linked from

- [core/converters](https://banes-lab.com/anatomy/deploy/folder-deploy-core-converters.md)
- [core/probes](https://banes-lab.com/anatomy/deploy/folder-deploy-core-probes.md)
- [core/reporters](https://banes-lab.com/anatomy/deploy/folder-deploy-core-reporters.md)
- [runtime/entrypoints](https://banes-lab.com/anatomy/deploy/folder-deploy-runtime-entrypoints.md)

## Source

```typescript
import {
    BACKUP_FIELD,
    DEPLOY_FAILURE_TITLE,
    DEPLOY_SUCCESS_TITLE,
    FILES_LABEL,
    MONITORING_FIELD,
    SITE_FIELD,
    SIZE_LABEL,
    STEPS_FIELD,
    SUMMARY_FIELD,
    SYSTEM_FIELD,
    VCS_FIELD,
} from "#configuration/strings/notification.strings";
import { ERROR_COLOR, SUCCESS_COLOR, UPDATES_ROLE } from "#configuration/constants/discord.constants";
import type { Journal, Outcome, UploadStats } from "#types/deployment.types";
import {
    NOT_AVAILABLE,
    NO_STATS,
    UPLOADED_SUFFIX,
    UPLOAD_FAILURES,
    UPLOAD_OF,
} from "#configuration/strings/deployment.strings";
import { bullet, code, fenced, lines, link } from "#core/converters/markdown.converter";
import { embed, failureAttachment, failureField, field, notify, timing } from "#core/reporters/notification.reporter";
import type { EmbedField } from "#types/discord.types";
import { MONITORING } from "#configuration/constants/deployment.constants";
import { SITE_URL } from "@banes-lab/web/core/assets/link.assets.ts";
import { describeCheckout } from "#core/probes/vcs.probe";
import { describeSystem } from "#core/probes/system.probe";
import { formatBytes } from "#core/converters/text.converter";

const summaryOf = function summaryOf(stats: UploadStats | null): string {
    if (stats === null) {
        return NO_STATS;
    }
    const files =
        String(stats.uploadedCount) +
        UPLOAD_OF +
        String(stats.totalFileCount) +
        UPLOADED_SUFFIX +
        String(stats.failedCount) +
        UPLOAD_FAILURES;
    const size = formatBytes(stats.totalBytes);
    return lines([bullet(FILES_LABEL, code(files)), bullet(SIZE_LABEL, code(size))]);
};

const sharedFields = function sharedFields(journal: Journal, outcome: Outcome): readonly EmbedField[] {
    return [
        field(BACKUP_FIELD, outcome.backup.length > 0 ? code(outcome.backup) : NOT_AVAILABLE, true),
        ...timing(outcome.span, outcome.failure.length === 0),
        field(SUMMARY_FIELD, summaryOf(outcome.stats)),
        field(STEPS_FIELD, fenced(journal.summary())),
        field(VCS_FIELD, describeCheckout()),
        field(SYSTEM_FIELD, describeSystem()),
    ];
};

const monitoringLinks = function monitoringLinks(): string {
    return lines(MONITORING.map(([label, url]) => link(label, url)));
};

export const reportDeployment = async function reportDeployment(
    journal: Journal,
    url: string,
    outcome: Outcome,
): Promise<boolean> {
    if (outcome.failure.length === 0) {
        const fields = [
            field(SITE_FIELD, link(SITE_URL, SITE_URL), true),
            ...sharedFields(journal, outcome),
            field(MONITORING_FIELD, monitoringLinks()),
        ];
        return notify(journal, url, "", embed(DEPLOY_SUCCESS_TITLE, SUCCESS_COLOR, fields));
    }
    const fields = [failureField(outcome.failure), ...sharedFields(journal, outcome)];
    return notify(
        journal,
        url,
        UPDATES_ROLE,
        embed(DEPLOY_FAILURE_TITLE, ERROR_COLOR, fields),
        failureAttachment(outcome.failure),
    );
};
```
