Skip to content

Commit bb63d7e

Browse files
arvi3411301wawhalrikinskscriptonistecthiender
authored
cli: allow managing actions (#3859)
Co-authored-by: Rishichandra Wawhal <rishichandra.wawhal@gmail.com> Co-authored-by: Rikin Kachhia <54616969+rikinsk@users.noreply.github.com> Co-authored-by: Aravind <aravindkp@outlook.in> Co-authored-by: Anon Ray <ecthiender@users.noreply.github.com> Co-authored-by: Shahidh K Muhammed <muhammedshahid.k@gmail.com>
1 parent 8df0151 commit bb63d7e

File tree

199 files changed

+17241
-2502
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

199 files changed

+17241
-2502
lines changed

.circleci/config.yml

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,45 @@ jobs:
353353
root: /build
354354
paths:
355355
- _cli_output
356+
357+
test_and_build_cli_ext:
358+
docker:
359+
- image: hasura/graphql-engine-extension-cli-builder:20200220
360+
working_directory: ~/graphql-engine
361+
steps:
362+
- attach_workspace:
363+
at: /build
364+
- *skip_job_on_ciignore
365+
- checkout
366+
- restore_cache:
367+
key:
368+
cli-ext-npm-cache-v1-{{ checksum "cli-ext/package.json" }}-{{ checksum "cli-ext/package-lock.json" }}
369+
- run:
370+
name: install dependencies
371+
working_directory: cli-ext
372+
command: make ci-deps
373+
- save_cache:
374+
key:
375+
cli-ext-npm-cache-v1-{{ checksum "cli-ext/package.json" }}-{{ checksum "cli-ext/package-lock.json" }}
376+
paths:
377+
- cli-ext/node_modules
378+
- ~/.npm
379+
- ~/.cache
380+
- run:
381+
name: build extension cli
382+
working_directory: cli-ext
383+
command: |
384+
npm install -g pkg
385+
npm run build
386+
make deploy
387+
make ci-copy-assets
388+
- store_artifacts:
389+
path: /build/_cli_ext_output
390+
destination: cli_ext
391+
- persist_to_workspace:
392+
root: /build
393+
paths:
394+
- _cli_ext_output
356395

357396
# build console assets
358397
build_console:
@@ -493,6 +532,10 @@ workflows:
493532
workflow_v20200120:
494533
jobs:
495534
- check_build_worthiness: *filter_only_vtags
535+
- test_and_build_cli_ext:
536+
<<: *filter_only_vtags
537+
requires:
538+
- check_build_worthiness
496539
- build_console:
497540
<<: *filter_only_vtags
498541
requires:
@@ -501,6 +544,11 @@ workflows:
501544
<<: *filter_only_vtags
502545
requires:
503546
- check_build_worthiness
547+
- test_cli_with_last_release:
548+
<<: *filter_only_vtags
549+
requires:
550+
- test_and_build_cli_ext
551+
- check_build_worthiness
504552
- build_image:
505553
<<: *filter_only_vtags
506554
requires:
@@ -544,13 +592,10 @@ workflows:
544592
- test_server_pg_9.5
545593
- server_unit_tests
546594
- test_server_upgrade
547-
- test_cli_with_last_release:
548-
<<: *filter_only_vtags
549-
requires:
550-
- check_build_worthiness
551595
- test_and_build_cli:
552596
<<: *filter_only_vtags
553597
requires:
598+
- test_and_build_cli_ext
554599
- build_server
555600
- test_console:
556601
<<: *filter_only_vtags

.circleci/console-builder.dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,4 @@ RUN apt-get update && apt-get install -y \
2626
&& rm -rf /usr/share/man/ \
2727
&& rm -rf /usr/share/locale/
2828

29-
ENV PATH "/usr/local/google-cloud-sdk/bin:$PATH"
29+
ENV PATH "/usr/local/google-cloud-sdk/bin:$PATH"

.circleci/deploy.sh

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ draft_github_release() {
5858
-r "$CIRCLE_PROJECT_REPONAME" \
5959
-b "${RELEASE_BODY}" \
6060
-draft \
61-
"$CIRCLE_TAG" /build/_cli_output/binaries/
61+
"$CIRCLE_TAG" /build/_cli_output/binaries/ /build/_cli_ext_output/*.tar.gz /build/_cli_ext_output/*.zip
6262
}
6363

6464
configure_git() {
@@ -95,6 +95,27 @@ deploy_console() {
9595
unset DIST_PATH
9696
}
9797

98+
deploy_cli_ext() {
99+
echo "deploying extension cli"
100+
101+
cd "$ROOT/cli-ext"
102+
export VERSION=$(../scripts/get-version.sh)
103+
export DIST_PATH="/build/_cli_ext_output"
104+
105+
configure_git
106+
git clone https://github.com/hasura/cli-plugins-index.git ~/plugins-index
107+
cd ~/plugins-index
108+
git checkout -b cli-ext-${LATEST_TAG}
109+
cp ${DIST_PATH}/manifest.yaml ./plugins/cli-ext.yaml
110+
git add .
111+
git commit -m "update cli-ext manifest to ${LATEST_TAG}"
112+
git push -q https://${GITHUB_TOKEN}@github.com/hasura/plugins-index.git cli-ext-${LATEST_TAG}
113+
hub pull-request -F- <<<"Update cli-ext manifest to ${LATEST_TAG}" -r ${REVIEWERS} -a ${REVIEWERS}
114+
115+
unset VERSION
116+
unset DIST_PATH
117+
}
118+
98119
# build and push container for auto-migrations
99120
build_and_push_cli_migrations_image() {
100121
IMAGE_TAG="hasura/graphql-engine:${CIRCLE_TAG}.cli-migrations"
@@ -167,6 +188,7 @@ deploy_console
167188
deploy_server
168189
if [[ ! -z "$CIRCLE_TAG" ]]; then
169190
build_and_push_cli_migrations_image
191+
deploy_cli_ext
170192

171193
# if this is a stable release, update all latest assets
172194
if [ $IS_STABLE_RELEASE = true ]; then
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
FROM node:12
2+
3+
ARG gcloud_version="207.0.0"
4+
5+
# install dependencies
6+
RUN apt-get update && apt-get install -y \
7+
netcat \
8+
libpq5 \
9+
libgtk2.0-0 \
10+
libnotify-dev \
11+
libgconf-2-4 \
12+
libnss3 \
13+
libxss1 \
14+
libasound2 \
15+
zip \
16+
xvfb \
17+
&& curl -Lo /tmp/gcloud-${gcloud_version}.tar.gz https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-sdk-${gcloud_version}-linux-x86_64.tar.gz \
18+
&& tar -xzf /tmp/gcloud-${gcloud_version}.tar.gz -C /usr/local \
19+
&& /usr/local/google-cloud-sdk/install.sh \
20+
&& apt-get -y auto-remove \
21+
&& apt-get -y clean \
22+
&& rm -rf /var/lib/apt/lists/* \
23+
&& rm -rf /usr/share/doc/ \
24+
&& rm -rf /usr/share/man/ \
25+
&& rm -rf /usr/share/locale/
26+
27+
ENV PATH "/usr/local/google-cloud-sdk/bin:$PATH"

.circleci/test-cli-with-last-release.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ PID=$!
3333
wait_for_port 8080
3434

3535
# test cli
36-
HASURA_GRAPHQL_TEST_ENDPOINT="http://localhost:8080" make test
36+
HASURA_GRAPHQL_TEST_ENDPOINT="http://localhost:8080" TEST_TAGS="latest_release" make test
3737

3838
# kill the running server
3939
kill -s INT $PID
@@ -47,5 +47,5 @@ PID=$!
4747
wait_for_port 8080
4848

4949
# test cli
50-
HASURA_GRAPHQL_TEST_ENDPOINT="http://localhost:8080" HASURA_GRAPHQL_TEST_ADMIN_SECRET="abcd" make test
50+
HASURA_GRAPHQL_TEST_ENDPOINT="http://localhost:8080" HASURA_GRAPHQL_TEST_ADMIN_SECRET="abcd" TEST_TAGS="latest_release" make test
5151
kill -s INT $PID

.circleci/test-cli.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ PID=$!
2929
wait_for_port 8080
3030

3131
# test cli
32-
HASURA_GRAPHQL_TEST_ENDPOINT="http://localhost:8080" make test
32+
HASURA_GRAPHQL_TEST_ENDPOINT="http://localhost:8080" TEST_TAGS="test_plugins" make test
3333
kill -s INT $PID
3434

3535
# start graphql-engine with admin secret

cli-ext/.babelrc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
presets: ["@babel/preset-env"],
3+
plugins: ["@babel/plugin-transform-async-to-generator"]
4+
}

cli-ext/.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
bin
2+
build
3+
src/shared
4+
_tmptests
5+
node_modules
6+
version.json

cli-ext/Makefile

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
BUILDDIR := bin
2+
ASSETS := $(BUILDDIR)/command-macos.tar.gz $(BUILDDIR)/command-linux.tar.gz $(BUILDDIR)/command-win.zip
3+
CHECKSUMS := $(patsubst %,%.sha256,$(ASSETS))
4+
5+
COMPRESS := gzip --best -k -c
6+
7+
ci-deps:
8+
if [ ! -d "node_modules" ]; then npm ci; fi
9+
10+
ci-copy-assets:
11+
mkdir -p /build/_cli_ext_output
12+
cp $(BUILDDIR)/* /build/_cli_ext_output/
13+
14+
.PRECIOUS: %.zip
15+
%.zip: %.exe
16+
cd $(BUILDDIR) && \
17+
zip $(patsubst $(BUILDDIR)/%, %, $@) $(patsubst $(BUILDDIR)/%, %, $<)
18+
19+
.PRECIOUS: %.gz
20+
%.gz: %
21+
$(COMPRESS) "$<" > "$@"
22+
23+
%.tar: %
24+
tar cf "$@" -C $(BUILDDIR) $(patsubst $(BUILDDIR)/%,%,$^)
25+
26+
%.sha256: %
27+
shasum -a 256 $< > $@
28+
29+
.PHONY: deploy
30+
deploy: $(CHECKSUMS)
31+
./scripts/generate-manifest.sh && \
32+
$(RM) $(BUILDDIR)/tmp.yaml
33+
34+
.PHONY: clean
35+
clean:
36+
$(RM) -r $(BUILDDIR)
37+

cli-ext/README.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
## Building the binaries
2+
3+
4+
```
5+
npm install
6+
npm run package
7+
```
8+
9+
The binaries will be placed in the `bin` directory at root. Copy the binary to your PATH as `cli-ext`.
10+
11+
## API
12+
13+
14+
```
15+
scaffolder sdl to '{ "types": { "enums": [], "scalars": [], "input_objects": [ { "name": "UserInput", "fields": [ { "name": "username", "type": "String", "description": "lalz" }, { "name": "password", "type": "String!", "description": "pass" } ] } ], "objects": [ { "name": "UserInfo", "fields": [ { "name": "accessToken", "type": "String", "description": "lolz" } ] } ] } }'
16+
17+
```
18+
19+
```
20+
scaffolder sdl from '{ "sdl": { "action": "type Mutation { actionName (arg1: SampleInput!): SampleOutput }", "types": "type SampleOutput { accessToken: String! } input SampleInput { username: String! password: String! }" }, "types": { "scalars": [], "enums": [], "input_objects": [], "objects": [] } }'
21+
```
22+
23+
```
24+
scaffolder scaffold '{ "action": { "action_name": "validatedUserInsert", "action_defn": { "kind": "synchronous", "webhook": "http://192.168.0.107:5000/actions", "arguments": [{ "name": "user", "type": "_user_insert_input!", "description": null }], "output_type": "UserInfo" } }, "types": { "enums": [{ "name": "_user_constraint", "values": [{ "value": "user_pkey", "description": null, "is_deprecated": null }], "description": null }, { "name": "_user_update_column", "values": [{ "value": "email", "description": null, "is_deprecated": null }, { "value": "id", "description": null, "is_deprecated": null }, { "value": "username", "description": null, "is_deprecated": null }], "description": null }, { "name": "_article_constraint", "values": [{ "value": "article_pkey", "description": null, "is_deprecated": null }], "description": null }, { "name": "_article_update_column", "values": [{ "value": "author_id", "description": null, "is_deprecated": null }, { "value": "content", "description": null, "is_deprecated": null }, { "value": "id", "description": null, "is_deprecated": null }, { "value": "title", "description": null, "is_deprecated": null }], "description": null }], "objects": [{ "name": "UserInfo", "fields": [{ "name": "userId", "type": "Int", "arguments": null, "description": null }, { "name": "accessToken", "type": "String", "arguments": null, "description": null }], "description": null, "relationships": [{ "name": "user", "remote_table": "user", "field_mapping": { "userId": "id" } }, { "name": "anotherrel", "remote_table": "article", "field_mapping": { "userId": "id" } }] }, { "name": "SMSInfo", "fields": [{ "name": "sms_id", "type": "String!", "arguments": null, "description": null }], "description": null, "relationships": null }], "scalars": [], "input_objects": [{ "name": "_user_insert_input", "fields": [{ "name": "articles", "type": "_article_arr_rel_insert_input", "description": null }, { "name": "email", "type": "String", "description": null }, { "name": "id", "type": "Int", "description": null }, { "name": "username", "type": "String", "description": null }], "description": null }, { "name": "_article_arr_rel_insert_input", "fields": [{ "name": "data", "type": "[_article_insert_input!]!", "description": null }, { "name": "on_conflict", "type": "_article_on_conflict", "description": null }], "description": null }, { "name": "_article_insert_input", "fields": [{ "name": "author_id", "type": "Int", "description": null }, { "name": "content", "type": "String", "description": null }, { "name": "id", "type": "Int", "description": null }, { "name": "title", "type": "String", "description": null }, { "name": "user", "type": "_user_obj_rel_insert_input", "description": null }], "description": null }, { "name": "_user_obj_rel_insert_input", "fields": [{ "name": "data", "type": "_user_insert_input!", "description": null }, { "name": "on_conflict", "type": "_user_on_conflict", "description": null }], "description": null }, { "name": "_user_on_conflict", "fields": [{ "name": "constraint", "type": "_user_constraint!", "description": null }, { "name": "update_columns", "type": "[_user_update_column!]!", "description": null }, { "name": "where", "type": "_user_bool_exp", "description": null }], "description": null }, { "name": "_user_bool_exp", "fields": [{ "name": "_and", "type": "[_user_bool_exp]", "description": null }, { "name": "_not", "type": "_user_bool_exp", "description": null }, { "name": "_or", "type": "[_user_bool_exp]", "description": null }, { "name": "articles", "type": "_article_bool_exp", "description": null }, { "name": "email", "type": "_String_comparison_exp", "description": null }, { "name": "id", "type": "_Int_comparison_exp", "description": null }, { "name": "username", "type": "_String_comparison_exp", "description": null }], "description": null }, { "name": "_article_bool_exp", "fields": [{ "name": "_and", "type": "[_article_bool_exp]", "description": null }, { "name": "_not", "type": "_article_bool_exp", "description": null }, { "name": "_or", "type": "[_article_bool_exp]", "description": null }, { "name": "author_id", "type": "_Int_comparison_exp", "description": null }, { "name": "content", "type": "_String_comparison_exp", "description": null }, { "name": "id", "type": "_Int_comparison_exp", "description": null }, { "name": "title", "type": "_String_comparison_exp", "description": null }, { "name": "user", "type": "_user_bool_exp", "description": null }], "description": null }, { "name": "_Int_comparison_exp", "fields": [{ "name": "_eq", "type": "Int", "description": null }, { "name": "_gt", "type": "Int", "description": null }, { "name": "_gte", "type": "Int", "description": null }, { "name": "_in", "type": "[Int!]", "description": null }, { "name": "_is_null", "type": "Boolean", "description": null }, { "name": "_lt", "type": "Int", "description": null }, { "name": "_lte", "type": "Int", "description": null }, { "name": "_neq", "type": "Int", "description": null }, { "name": "_nin", "type": "[Int!]", "description": null }], "description": null }, { "name": "_String_comparison_exp", "fields": [{ "name": "_eq", "type": "String", "description": null }, { "name": "_gt", "type": "String", "description": null }, { "name": "_gte", "type": "String", "description": null }, { "name": "_ilike", "type": "String", "description": null }, { "name": "_in", "type": "[String!]", "description": null }, { "name": "_is_null", "type": "Boolean", "description": null }, { "name": "_like", "type": "String", "description": null }, { "name": "_lt", "type": "String", "description": null }, { "name": "_lte", "type": "String", "description": null }, { "name": "_neq", "type": "String", "description": null }, { "name": "_nilike", "type": "String", "description": null }, { "name": "_nin", "type": "[String!]", "description": null }, { "name": "_nlike", "type": "String", "description": null }, { "name": "_nsimilar", "type": "String", "description": null }, { "name": "_similar", "type": "String", "description": null }], "description": null }, { "name": "_article_on_conflict", "fields": [{ "name": "constraint", "type": "_article_constraint!", "description": null }, { "name": "update_columns", "type": "[_article_update_column!]!", "description": null }, { "name": "where", "type": "_article_bool_exp", "description": null }], "description": null }, { "name": "SMSInput", "fields": [{ "name": "sms", "type": "String", "description": null }, { "name": "is_international", "type": "Boolean", "description": null }, { "name": "price", "type": "[Price]", "description": null }], "description": null }, { "name": "Price", "fields": [{ "name": "value", "type": "String", "description": null }], "description": null }] }, "framework": "typescript-express" }'
25+
```
26+
27+
## Templaters
28+
29+
The templaters are present in the `src/templaters` directory. You can modify the templaters and build.
30+
Each templater function must return an array of file objects. Something like:
31+
32+
```
33+
[
34+
{
35+
"name": "filename1.js",
36+
"content": "filename1 content"
37+
},
38+
{
39+
"name": "filename2.js",
40+
"content": "filename2 content"
41+
}
42+
]
43+
```
44+
45+
These files will be generated in the PWD of execution.

0 commit comments

Comments
 (0)