Skip to content

Commit

Permalink
JSDoc, deno.jsonc, return type tweaks; prep for JSR.io publish test (
Browse files Browse the repository at this point in the history
…#8)

* JSdoc tweaks, added an additional test, tweaked return type when creating a message boundary protocol implementation (it always contains a `getCLIFlags` method), removed deprecated nested options from deno.jsonc, changed coverage task to report detailed coverage.

* Add deno.land shim modules to root of project

* move readme back to project root

* exclude a few files in prep for jsr publishing

* export a few different entrypoints to jsr

* add a deployment/publish workflow for JSR.
  • Loading branch information
Fil Maj authored Jun 14, 2024
1 parent 761d788 commit a4f8b90
Show file tree
Hide file tree
Showing 14 changed files with 133 additions and 94 deletions.
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": {
".": "./src/mod.ts",
"./mock": "./src/mock.ts",
"./types": "./src/types.ts"
},
"fmt": {
"files": {
"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";
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 {
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';

0 comments on commit a4f8b90

Please sign in to comment.