Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JSDoc, deno.jsonc, return type tweaks; prep for JSR.io publish test #8

Merged
merged 14 commits into from
Jun 14, 2024
17 changes: 9 additions & 8 deletions .github/maintainers_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,19 +47,20 @@ Releases for this library are automatically generated off of git tags. Before cr

To create a new release:

1. Create a new GitHub Release from the [Releases page](https://github.com/slackapi/deno-slack-builder/releases) by clicking the "Draft a new release" button.
2. Input a new version manually into the "Choose a tag" input. You can start off by incrementing the version to reflect a patch. (i.e. 1.16.0 -> 1.16.1)
1. Create a PR/commit that bumps the `version` inside `deno.jsonc` to equal the new version you want to release. Land this commit/merge this PR into `main`. Read ahead to point #3 for tips on how to determine what the new version should be. You can start off by incrementing the version to reflect a patch. (i.e. 1.16.0 -> 1.16.1)
2. Create a new GitHub Release from the [Releases page](https://github.com/slackapi/deno-slack-builder/releases) by clicking the "Draft a new release" button.
3. Input the new version manually into the "Choose a tag" input.
* After you input the new version, click the "Create a new tag: x.x.x on publish" button. This won't create your tag immediately.
* Auto-generate the release notes by clicking the "Auto-generate release notes" button. This will pull in changes that will be included in your release.
* Edit the resulting notes to ensure they have decent messaging that are understandable by non-contributors, but each commit should still have it's own line.
* Flip to the preview mode and review the pull request labels of the changes included in this release (i.e. `semver:minor` `semver:patch`, `semver:major`). Tip: Your release version should be based on the tag of the largest change, so if this release includes a `semver:minor`, the release version in your tag should be upgraded to reflect a minor.
* Ensure that this version adheres to [semantic versioning][semver]. See [Versioning](#versioning-and-tags) for correct version format. Version tags should match the following pattern: `1.0.1` (no `v` preceding the number).
3. Set the "Target" input to the "main" branch.
4. Name the release title after the version tag.
5. Make any adjustments to generated release notes to make sure they are accessible and approachable and that an end-user with little context about this project could still understand.
6. Make sure "This is a pre-release" is _not_ checked.
7. Publish the release by clicking the "Publish release" button!
8. After a few minutes, the corresponding version will be available on https://deno.land/x/deno_slack_protocols.
4. Set the "Target" input to the "main" branch.
5. Name the release title after the version tag.
6. Make any adjustments to generated release notes to make sure they are accessible and approachable and that an end-user with little context about this project could still understand.
7. Make sure "This is a pre-release" is _not_ checked.
8. Publish the release by clicking the "Publish release" button!
9. After a few minutes, the corresponding version will be available on https://deno.land/x/deno_slack_protocols and https://jsr.io/@slack/protocols.

## Workflow

Expand Down
16 changes: 16 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: Publish

on:
push:
tags:
- '*'

jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write # The OIDC ID token is used for authentication with JSR.
steps:
- uses: actions/checkout@v4
- run: npx jsr publish
1 change: 0 additions & 1 deletion README.md

This file was deleted.

40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# deno-slack-protocols

[![codecov](https://codecov.io/gh/slackapi/deno-slack-protocols/graph/badge.svg?token=SR0MMXTQRW)](https://codecov.io/gh/slackapi/deno-slack-protocols)

This library is a utility for use by Slack's next-generation application
platform, focused on remixable units of functionality encapsulated as ephemeral
functions. It implements the rules for communication (i.e. the protocol) between
[Slack CLI][cli] and any Slack app development SDKs.

This is separate from the [deno-slack-hooks][hooks] project, which implements
the various APIs encapsulating work delegation from the CLI to the SDK. The
[deno-slack-hooks][hooks] project implements the API, which uses this library
under the hood.

## Requirements

This library requires a recent (at least 1.44) version of
[deno](https://deno.land).

## Running Tests

If you make changes to this repo, or just want to make sure things are working
as desired, you can run:

deno task test

To get a full test coverage report, run:

deno task test:coverage

---

### Getting Help

We welcome contributions from everyone! Please check out our
[Contributor's Guide](https://github.com/slackapi/deno-slack-protocols/blob/main/.github/CONTRIBUTING.md)
for how to contribute in a helpful and collaborative way.

[cli]: https://github.com/slackapi/slack-cli
[hooks]: https://github.com/slackapi/deno-slack-hooks
48 changes: 28 additions & 20 deletions deno.jsonc
Original file line number Diff line number Diff line change
@@ -1,31 +1,39 @@
{
"$schema": "https://deno.land/x/deno/cli/schemas/config-file.v1.json",
"name": "@slack/protocols",
"version": "0.0.2-pre.2",
"exports": {
Copy link
Contributor

@WilliamBergamin WilliamBergamin Jun 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love this export implementation 💯

".": "./src/mod.ts",
"./mock": "./src/mock.ts",
"./types": "./src/types.ts"
},
"fmt": {
"files": {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The files and options keys are deprecated, and deno would warn about using them, so removed them.

"include": ["src", "docs", "README.md"]
},
"options": {
"semiColons": true,
"indentWidth": 2,
"lineWidth": 80,
"proseWrap": "always",
"singleQuote": false,
"useTabs": false
}
"include": ["src", "docs", "README.md"],
"semiColons": true,
"indentWidth": 2,
"lineWidth": 80,
"proseWrap": "always",
"singleQuote": false,
"useTabs": false
},
"imports": {
"@std/assert": "jsr:@std/assert@^0.226.0",
"@std/cli": "jsr:@std/cli@^0.224.6",
"@std/testing": "jsr:@std/testing@^0.225.1"
},
"lint": {
"files": {
"include": ["src"]
}
"include": ["src"]
},
"test": {
"files": {
"include": ["src/tests.ts"]
}
"lock": false,
"publish": {
"exclude": ["mod.ts", "mock.ts", "types.ts", ".github", ".vscode"]
},
"tasks": {
"test": "deno fmt --check && deno lint && deno test --allow-read --allow-net",
"generate-lcov": "rm -rf .coverage && deno test --reporter=dot --allow-read --allow-net --coverage=.coverage && deno coverage --exclude=fixtures --exclude=test --lcov --output=lcov.info .coverage",
"test:coverage": "deno task generate-lcov && deno coverage --exclude=fixtures --exclude=test .coverage src"
"generate-lcov": "rm -rf .coverage && deno test --allow-read --allow-net --coverage=.coverage && deno coverage --exclude=fixtures --exclude=test --lcov --output=lcov.info .coverage",
"test:coverage": "deno task generate-lcov && deno coverage --detailed --exclude=fixtures --exclude=test .coverage src"
},
"test": {
"include": ["src/tests.ts"]
}
}
4 changes: 4 additions & 0 deletions mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// This file only exists as a 'shim' for deno.land, as this package was
// previously published to deno.land to only include the contents of the `./src`
// subdirectory.
export * from './src/mock.ts';
4 changes: 4 additions & 0 deletions mod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// This file only exists as a 'shim' for deno.land, as this package was
// previously published to deno.land to only include the contents of the `./src`
// subdirectory.
export * from './src/mod.ts';
40 changes: 0 additions & 40 deletions src/README.md

This file was deleted.

1 change: 0 additions & 1 deletion src/deps.ts

This file was deleted.

10 changes: 0 additions & 10 deletions src/dev_deps.ts

This file was deleted.

6 changes: 5 additions & 1 deletion src/mock.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import type { Protocol } from "./types.ts";
import { spy } from "./dev_deps.ts";
import { spy } from "@std/testing/mock";

/**
* A mock protocol constructor function, composed of purely spy functions, for use in testing.
*/
export const MockProtocol = function (): Protocol {
return {
name: "MockProtocol",
log: spy(),
warn: spy(),
error: spy(),
Expand Down
15 changes: 8 additions & 7 deletions src/mod.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { parse } from "./deps.ts";
import { parseArgs } from "@std/cli/parse-args";
WilliamBergamin marked this conversation as resolved.
Show resolved Hide resolved
import type { Protocol } from "./types.ts";

// List of slack-cli communication protocols supported
Expand All @@ -13,10 +13,9 @@ const SUPPORTED_NAMED_PROTOCOLS = [
* and the CLI reads both stdout and stderr and combines them to interpret the hook response.
* This simplistic protocol has inherent limitations: cannot log diagnostic info!
* @param args command-line arguments passed to this process
* @returns {Protocol}
*/
export const BaseProtocol = function (args: string[]): Protocol {
const { manifest: manifestOnly = false } = parse(args);
const { manifest: manifestOnly = false } = parseArgs(args);
// If the particular hook invocation is requesting for manifest generation, we ensure any logging is a no-op,
// so as to not litter stdout with logging - and confuse the CLI's manifest JSON payload parsing.
const loggerMethod = manifestOnly ? () => {} : console.log;
Expand All @@ -32,9 +31,12 @@ export const BaseProtocol = function (args: string[]): Protocol {
/**
* Protocol implementation that only uses stdout, but uses message boundaries to differentiate between
* diagnostic information and hook responses.
* @param args command-line arguments passed to this process
*/
export const MessageBoundaryProtocol = function (args: string[]): Protocol {
const { boundary } = parse(
export const MessageBoundaryProtocol = function (
args: string[],
): Required<Pick<Protocol, "getCLIFlags">> & Protocol {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The base Protocol interface sets getCLIFlags as an optional key. However, the Message Boundary protocol always returns this key, so tweaking the type to make that a required property.

const { boundary } = parseArgs(
args,
);
if (!boundary) throw new Error("no boundary argument provided!");
Expand Down Expand Up @@ -62,10 +64,9 @@ const PROTOCOL_MAP = {
* Based on the arguments provided by the CLI to the SDK hook process, returns an appropriate Protocol interface
* for communicating with the CLI over the specified protocol.
* @param args string[] An array of strings representing the command-line flags/arguments passed to the hook
* @returns Protocol An object implementing the Protocol interface
*/
export const getProtocolInterface = function (args: string[]): Protocol {
const { protocol: protocolRequestedByCLI } = parse(
const { protocol: protocolRequestedByCLI } = parseArgs(
args,
);
if (protocolRequestedByCLI) {
Expand Down
17 changes: 13 additions & 4 deletions src/tests.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { assertSpyCall, type Spy, spy } from "@std/testing/mock";
import {
assertEquals,
assertMatch,
assertNotEquals,
assertSpyCall,
assertThrows,
Spy,
spy,
} from "./dev_deps.ts";
} from "@std/assert";
import {
BaseProtocol,
getProtocolInterface,
Expand Down Expand Up @@ -45,6 +44,16 @@ Deno.test("MessageBoundaryProtocol", async (t) => {
globalThis.console.log = origLog;
},
);
await t.step(
"should return a `getCLIFlags` method that returns correct --protocol and --boundary flags",
() => {
const providedFlags = ["--boundary=12345"];
const prot = MessageBoundaryProtocol(providedFlags);
const flags = prot.getCLIFlags();
assertMatch(flags[0], /message-boundaries/);
assertEquals(flags[1], providedFlags[0]);
},
);
});

Deno.test("getProtocolInterface()", async (t) => {
Expand Down
4 changes: 2 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ export interface Protocol {
warn: typeof console.warn;
/**
* Utility method for responding to CLI hook invocations.
* @param data Stringified JSON to return to the CLI
* @param {data} Stringified JSON to return to the CLI
* @returns
*/
respond: (data: string) => void;
/**
* Retrieve all command-line flags related to the specific protocol implementation. May be useful if child processes are being
* spawned by the SDK, such as in local-run mode of deno-slack-runtime.
* @returns string[] An array of strings representing any protocol-specific command-line flags passed from the CLI to the hook, if applicable
* @returns {string[]} An array of strings representing any protocol-specific command-line flags passed from the CLI to the hook, if applicable
* to the specific protocol implementation
*/
getCLIFlags?: () => string[];
Expand Down
4 changes: 4 additions & 0 deletions types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// This file only exists as a 'shim' for deno.land, as this package was
// previously published to deno.land to only include the contents of the `./src`
// subdirectory.
export * from './src/types.ts';