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

Introduce a @slack/cli-hooks package that implements Slack CLI hooks #1714

Merged
merged 48 commits into from
Jan 26, 2024
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
a6c1ffb
feat: introduce a package for slack cli hooks
zimeg Jan 5, 2024
791d35e
fix: correct errors in hooks package before publishing
zimeg Jan 9, 2024
49e6f3d
feat: convert scripts to typescript for type safety
zimeg Jan 9, 2024
808fba4
chore: bump package version after accidental publish
zimeg Jan 9, 2024
8a889eb
feat: remove a build step but keep typings with jsdoc
zimeg Jan 10, 2024
5827a8c
chore: merge w main
zimeg Jan 10, 2024
e169b70
test: add coverage and fix problems in the scripts
zimeg Jan 10, 2024
63ba992
ci: include the hooks package in automated tests
zimeg Jan 10, 2024
bd4da54
ci: continue running all tests even if one fails
zimeg Jan 10, 2024
cbdfb7d
test: compare error outputs of different node versions
zimeg Jan 10, 2024
938dc24
docs: include instructions for app setup in the readme
zimeg Jan 11, 2024
fb2ee36
chore: merge w main
zimeg Jan 11, 2024
0fbb96e
chore: bump the package version another patch
zimeg Jan 11, 2024
54d05a9
style: improve wording and such semantics
zimeg Jan 11, 2024
81e7a6a
test: update expected output with actual output
zimeg Jan 11, 2024
75d1994
fix: remove script extensions from get-manifest
zimeg Jan 11, 2024
f04d115
docs: switch information about setup for hooks details
zimeg Jan 11, 2024
6866520
refactor: rename this package from hooks to cli-hooks
zimeg Jan 11, 2024
72b0d00
fix: run tests for the newly named package instead
zimeg Jan 11, 2024
c6f3da2
feat: default to an app.js script in the start hook
zimeg Jan 12, 2024
46d7f08
chore: merge w main
zimeg Jan 16, 2024
e8963b1
fix: lookup manifest file across different operating systems
zimeg Jan 23, 2024
02dc946
chore: bump the package patch version
zimeg Jan 23, 2024
a800d5a
refactor: export hook as modules instead of iife scripts
zimeg Jan 24, 2024
a4ba93e
style: remove leftover jsdoc from a testing iteration
zimeg Jan 24, 2024
287b21b
feat: adapt the message boundaries protocol implementation
zimeg Jan 24, 2024
c96858b
feat: remove upgrade checks for the deno sdk
zimeg Jan 25, 2024
af8c9a3
feat: compare package versions with the semver package
zimeg Jan 25, 2024
a4c2cc0
docs: note steps for troubleshooting global installations
zimeg Jan 25, 2024
0e5cf60
chore: include the mit license with this package
zimeg Jan 25, 2024
953588b
chore: bump the package patch version
zimeg Jan 25, 2024
143075a
fix: include semver types for the typescript typechecker
zimeg Jan 25, 2024
3587643
fix: follow script symbolic links to the actual file path
zimeg Jan 25, 2024
26ed497
chore: bump the package patch version
zimeg Jan 25, 2024
7773a9d
fix: include protocols in the packaged bundle
zimeg Jan 25, 2024
d5fd65d
refactor: rename protocol test file to match the implementation
zimeg Jan 25, 2024
9aab3c9
chore: bump the package patch version
zimeg Jan 25, 2024
a6e72d3
fix: log responses with the protocol response
zimeg Jan 26, 2024
cb1c85e
feat: remove extraneous logs from the start hook
zimeg Jan 26, 2024
614a965
chore: bump the package patch version
zimeg Jan 26, 2024
f923d94
test: display coverage after testing results
zimeg Jan 26, 2024
91e139a
fix: use the exported `SUPPORTED_NAMED_PROTOCOLS` in get-hooks
zimeg Jan 26, 2024
9a2b931
test: assert missing boundary error text matches
zimeg Jan 26, 2024
c7ded6e
docs: improve remediation errors for missing start tokens
zimeg Jan 26, 2024
6fe204b
refactor: call the base protocol the default protocol
zimeg Jan 26, 2024
c3b804e
refactor: get the protocol implementation and not an interface
zimeg Jan 26, 2024
980eee0
chore: bump the package patch version
zimeg Jan 26, 2024
ab411ac
chore: release a major version of this package
zimeg Jan 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion .github/workflows/ci-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,18 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 10
strategy:
fail-fast: false
matrix:
node-version: [18.x, 20.x]
package: [packages/logger, packages/oauth, packages/rtm-api, packages/socket-mode, packages/types, packages/web-api, packages/webhook]
package:
- packages/hooks
- packages/logger
- packages/oauth
- packages/rtm-api
- packages/socket-mode
- packages/types
- packages/web-api
- packages/webhook
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
Expand Down
7 changes: 7 additions & 0 deletions packages/hooks/.c8rc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"include": ["src/*.js"],
"exclude": ["**/*.spec.js"],
"reporter": ["lcov"],
"all": false,
"cache": true
}
1 change: 1 addition & 0 deletions packages/hooks/.eslintignore
180 changes: 180 additions & 0 deletions packages/hooks/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
// SlackAPI JavaScript style
// ---
// This style helps maintainers enforce safe and consistent programming practices in this project. It is not meant to be
// comprehensive on its own or vastly different from existing styles. The goal is to inherit and aggregate as many of
// the communities' recommended styles for the technologies used as we can. When, and only when, we have a stated need
// to differentiate, we add more rules (or modify options). Therefore, the fewer rules directly defined in this file,
// the better.
//
// These styles are a subset of the shared JavaScript and TypeScript configurations to only target JavaScript packages.

module.exports = {
// This is a root of the project, ESLint should not look through parent directories to find more config
root: true,

ignorePatterns: [
// Ignore all build outputs and artifacts (node_modules, dotfiles, and dot directories are implicitly ignored)
'/coverage',
],

// These environments contain lists of global variables which are allowed to be accessed
env: {
// The target node version (v18) supports all important ES2022 features: https://node.green
es2022: true,
node: true,
},

extends: [
// ESLint's recommended built-in rules: https://eslint.org/docs/rules/
'eslint:recommended',

// Node plugin's recommended rules: https://github.com/mysticatea/eslint-plugin-node
'plugin:node/recommended',

// AirBnB style guide (without React) rules: https://github.com/airbnb/javascript.
'airbnb-base',

// JSDoc plugin's recommended rules
'plugin:jsdoc/recommended',
],

rules: {
// JavaScript rules
// ---
// The top level of this configuration contains rules which apply to JavaScript.
//
// This section does not contain rules meant to override options or disable rules in the base configurations
// (ESLint, Node, AirBnb). Those rules are added in the final override.

// Eliminate tabs to standardize on spaces for indentation. If you want to use tabs for something other than
// indentation, you may need to turn this rule off using an inline config comments.
'no-tabs': 'error',

// Bans use of comma as an operator because it can obscure side effects and is often an accident.
'no-sequences': 'error',

// Disallow the use of process.exit()
'node/no-process-exit': 'error',

// Allow safe references to functions before the declaration.
'no-use-before-define': ['error', 'nofunc'],

// Allow scripts for hooks implementations.
'node/shebang': 'off',

// Allow unlimited classes in a file.
'max-classes-per-file': 'off',

// Disallow invocations of require(). This will help make imports more consistent and ensures a smoother
// transition to the best future syntax.
'import/no-commonjs': ['error', {
allowConditionalRequire: false,
}],

// Don't verify that all named imports are part of the set of named exports for the referenced module. The
// TypeScript compiler will already perform this check, so it is redundant.
'import/named': 'off',
'node/no-missing-import': 'off',

// Allow use of import and export syntax, despite it not being supported in the node versions. Since this
// project is transpiled, the ignore option is used. Overrides node/recommended.
'node/no-unsupported-features/es-syntax': ['error', { ignores: ['modules'] }],

'operator-linebreak': ['error', 'after', {
overrides: { '=': 'none' }
}],
},

overrides: [
{
files: ['**/*.js'],
rules: {
// Override rules
// ---
// This level of this configuration contains rules which override options or disable rules in the base
// configurations in JavaScript.

// Increase the max line length to 120. The rest of this setting is copied from the AirBnB config.
'max-len': ['error', 120, 2, {
ignoreUrls: true,
ignoreComments: false,
ignoreRegExpLiterals: true,
ignoreStrings: true,
ignoreTemplateLiterals: true,
}],

// Restrict the use of backticks to declare a normal string. Template literals should only be used when the
// template string contains placeholders. The rest of this setting is copied from the AirBnb config.
quotes: ['error', 'single', { avoidEscape: true, allowTemplateLiterals: false }],

// The server side Slack API uses snake_case for parameters often.
//
// For mocking and override support, we need to allow snake_case.
// Allow leading underscores for parameter names, which is used to acknowledge unused variables in TypeScript.
// Also, enforce camelCase naming for variables. Ideally, the leading underscore could be restricted to only
// unused parameter names, but this rule isn't capable of knowing when a variable is unused. The camelcase and
// no-underscore-dangle rules are replaced with the naming-convention rule because this single rule can serve
// both purposes, and it works fine on non-TypeScript code.
camelcase: 'error',
'no-underscore-dangle': 'error',
'no-unused-vars': [
'error',
{
varsIgnorePattern: '^_',
argsIgnorePattern: '^_'
}
],

// Allow cyclical imports. Turning this rule on is mainly a way to manage the performance concern for linting
// time. Our projects are not large enough to warrant this. Overrides AirBnB styles.
'import/no-cycle': 'off',

// Prevent importing submodules of other modules. Using the internal structure of a module exposes
// implementation details that can potentially change in breaking ways. Overrides AirBnB styles.
'import/no-internal-modules': ['error', {
// Use the following option to set a list of allowable globs in this project.
allow: [
'**/middleware/*', // the src/middleware directory doesn't export a module, it's just a namespace.
'**/receivers/*', // the src/receivers directory doesn't export a module, it's just a namespace.
'**/types/**/*',
'**/types/*', // type heirarchies should be used however one wants
],
}],

// Remove the minProperties option for enforcing line breaks between braces. The AirBnB config sets this to 4,
// which is arbitrary and not backed by anything specific in the style guide. If we just remove it, we can
// rely on the max-len rule to determine if the line is too long and then enforce line breaks. Overrides AirBnB
// styles.
'object-curly-newline': ['error', { multiline: true, consistent: true }],
},
},
{
files: ['src/**/*.spec.js'],
rules: {
// Test-specific rules
// ---
// Rules that only apply to JavaScript _test_ source files

// With Mocha as a test framework, it is sometimes helpful to assign
// shared state to Mocha's Context object, for example in setup and
// teardown test methods. Assigning stub/mock objects to the Context
// object via `this` is a common pattern in Mocha. As such, using
// `function` over the the arrow notation binds `this` appropriately and
// should be used in tests. So: we turn off the prefer-arrow-callback
// rule.
// See https://github.com/slackapi/bolt-js/pull/1012#pullrequestreview-711232738
// for a case of arrow-vs-function syntax coming up for the team
'prefer-arrow-callback': 'off',
// Using ununamed functions (e.g., null logger) in tests is fine
'func-names': 'off',
// In tests, don't force constructing a Symbol with a descriptor, as
// it's probably just for tests
'symbol-description': 'off',

'node/no-unpublished-import': ['error', {
"allowModules": ["mocha"],
}],
},
},
],
};
6 changes: 6 additions & 0 deletions packages/hooks/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Node and NPM stuff
/node_modules
package-lock.json

# Coverage carryover
/coverage
105 changes: 105 additions & 0 deletions packages/hooks/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Slack CLI Hooks
zimeg marked this conversation as resolved.
Show resolved Hide resolved

The `@slack/hooks` package contains scripts that implement the contract between
zimeg marked this conversation as resolved.
Show resolved Hide resolved
the [Slack CLI][cli] and [Bolt for JavaScript][bolt].

## Requirements

This package supports Node v18 and higher. It's highly recommended to use [the
latest LTS version of Node][node].

An updated version of the Slack CLI is also encouraged while using this package.

## Installation
zimeg marked this conversation as resolved.
Show resolved Hide resolved

Add this package as a development dependency for your project with the following
command:

```sh
$ npm install --save-dev @slack/hooks
```

Follow [the installation guide][install] to download the Slack CLI and easily
run the scripts included in this package.

## Usage

Scripts in this package are used by the Slack CLI when running certain commands.

These scripts are automatically added to the `./node_modules/.bin` directory of
a project when this package is installed.

### Preparing a project manifest

Define the [manifest of your application][manifest] in a `manifest.json` file:

```json
{
"display_information": {
"name": "Hooks"
},
"settings": {
"org_deploy_enabled": true,
"socket_mode_enabled": true,
},
"features": {
"bot_user": {
"display_name": "Hooks"
}
},
"oauth_config": {
"scopes": {
"bot": ["chat:write"]
}
}
}
```

Or collect an existing manifest for your app from the **App Manifest** tab on
[App Config][config].

### Configuring the hooks interface

Configure a Bolt project to use these scripts by creating a `slack.json` file in
the root directory of your project:

```json
{
"hooks": {
"get-hooks": "npx -q --no-install -p @slack/hooks slack-cli-get-hooks"
}
}
```

### Running the app

With this package configured and the Slack CLI installed, you're ready to run
your app:

```sh
$ slack run
```

## Getting help

If you get stuck, we're here to help. The following are the best ways to get
assistance working through your issue:

* [Issue Tracker][issues] for questions, feature requests, bug reports and
general discussion related to these packages. Try searching before you create
a new issue.
* [Email us][email]: `[email protected]`
* [Community Slack][community]: a Slack community for developers building all
kinds of Slack apps. You can find the maintainers and users of these packages
in **#lang-javascript**.

<!-- a collection of links -->
[bolt]: https://github.com/slackapi/bolt-js
[cli]: https://api.slack.com/automation/cli
[community]: https://community.slack.com/
[config]: https://api.slack.com/apps
[email]: mailto:[email protected]
[install]: https://api.slack.com/automation/cli/install
[issues]: http://github.com/slackapi/node-slack-sdk/issues
[manifest]: https://api.slack.com/reference/manifests
[node]: https://github.com/nodejs/Release#release-schedule
32 changes: 32 additions & 0 deletions packages/hooks/jsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"compilerOptions": {
"target": "es2022",
"module": "commonjs",
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"outDir": "dist",
"checkJs": true,

"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,

"moduleResolution": "node",
"baseUrl": ".",
"paths": {
"*": ["./types/*"]
},
"esModuleInterop" : true,
},
"include": [
"src/**/*"
],
"jsdoc": {
"out": "support/jsdoc",
"access": "public"
}
}

Loading
Loading