├── .husky
├── .gitignore
└── pre-commit
├── .tool-versions
├── _img
├── labels.png
├── topics.png
└── repolist.png
├── public
├── favicon.png
├── index.html
└── global.css
├── Jenkinsfile_k8s
├── src
├── main.js
├── App.svelte
├── PluginLabels.svelte
├── RepoList.svelte
└── GithubLabels.svelte
├── graphql
├── getLabels.graphql
├── updateTopics.graphql
└── getTopics.graphql
├── .editorconfig
├── Dockerfile
├── .do
└── deploy.template.yaml
├── NOTES.md
├── .eslintrc.js
├── Makefile
├── README.md
├── bin
└── www
├── labels.yaml
├── package.json
├── .gitignore
├── .eslintignore
├── .dockerignore
├── webpack.config.js
├── scripts
└── setupTypeScript.js
├── index.js
└── app
└── routes.js
/.husky/.gitignore:
--------------------------------------------------------------------------------
1 | _
2 |
--------------------------------------------------------------------------------
/.tool-versions:
--------------------------------------------------------------------------------
1 | nodejs 14.9.0
2 |
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | . "$(dirname "$0")/_/husky.sh"
3 |
4 | npm run lint
5 |
--------------------------------------------------------------------------------
/_img/labels.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jenkins-infra/docker-plugins-self-service/main/_img/labels.png
--------------------------------------------------------------------------------
/_img/topics.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jenkins-infra/docker-plugins-self-service/main/_img/topics.png
--------------------------------------------------------------------------------
/_img/repolist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jenkins-infra/docker-plugins-self-service/main/_img/repolist.png
--------------------------------------------------------------------------------
/public/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jenkins-infra/docker-plugins-self-service/main/public/favicon.png
--------------------------------------------------------------------------------
/Jenkinsfile_k8s:
--------------------------------------------------------------------------------
1 | parallelDockerUpdatecli([imageName: 'plugins-self-service', rebuildImageOnPeriodicJob: false])
2 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import App from './App.svelte';
2 |
3 | const app = new App({
4 | target: document.body,
5 | props: { }
6 | });
7 |
8 | export default app;
9 |
--------------------------------------------------------------------------------
/graphql/getLabels.graphql:
--------------------------------------------------------------------------------
1 | query getLabels($owner: String!, $name: String!) {
2 | repository(owner: $owner, name: $name) {
3 | id
4 | labels (first:100) {
5 | nodes {
6 | id
7 | name
8 | color
9 | description
10 | }
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/graphql/updateTopics.graphql:
--------------------------------------------------------------------------------
1 | mutation($clientMutationId: String!, $repositoryId: ID!, $topicNames: [String!]!) {
2 | updateTopics(input: {
3 | clientMutationId: $clientMutationId,
4 | repositoryId: $repositoryId,
5 | topicNames: $topicNames
6 | }) {
7 | clientMutationId
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/graphql/getTopics.graphql:
--------------------------------------------------------------------------------
1 | query getTopics($owner: String!, $name: String!) {
2 | repository(owner: $owner, name: $name) {
3 | id
4 | repositoryTopics (first:100) {
5 | nodes {
6 | id
7 | topic {
8 | id
9 | name
10 | }
11 | url
12 | }
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome: http://EditorConfig.org
2 |
3 | # top-most EditorConfig file
4 | root = true
5 |
6 | # Unix-style newlines with a newline ending every file
7 | [*]
8 | end_of_line = lf
9 | insert_final_newline = true
10 | indent_style = space
11 | indent_size = 2
12 | charset = utf-8
13 |
14 | [Makefile]
15 | indent_style = tab
16 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:14 as build
2 | WORKDIR /home/node
3 |
4 | ENV NODE_ENV=development
5 | COPY package*.json ./
6 | RUN npm install
7 | COPY . .
8 | RUN npm run build
9 |
10 | FROM node:14
11 |
12 | ENV NODE_ENV=production
13 | USER node
14 | WORKDIR /home/node
15 | RUN mkdir sessions
16 | COPY package*.json ./
17 | RUN npm install
18 | COPY . .
19 | COPY --from=build /home/node/public/build ./public/build/
20 |
21 | CMD ["npm","run","start"]
22 |
--------------------------------------------------------------------------------
/.do/deploy.template.yaml:
--------------------------------------------------------------------------------
1 | name: plugins-self-service
2 | region: nyc
3 | services:
4 | - dockerfile_path: Dockerfile
5 | envs:
6 | - key: GITHUB_CLIENT_ID
7 | type: SECRET
8 | - key: GITHUB_CLIENT_SECRET
9 | type: SECRET
10 | github:
11 | branch: master
12 | deploy_on_push: true
13 | repo: halkeye/plugins-self-service
14 | http_port: 5000
15 | instance_count: 1
16 | instance_size_slug: basic-xs
17 | name: plugins-self-service
18 | routes:
19 | - path: /
20 |
--------------------------------------------------------------------------------
/NOTES.md:
--------------------------------------------------------------------------------
1 | https://github.com/octokit/graphql.js/issues/61#issuecomment-643392492
2 | https://www.npmjs.com/package/@octokit/graphql#send-a-simple-query
3 |
4 | * App
5 | * -> Has JWT Token?
6 | * -> Show Repos.svelte
7 | * -> Show Welcome Dialog with action button to Redirect to /login
8 |
9 |
10 | * Repos.svelte
11 | * -> Add in button to set common topics
12 | * -> Just a hard coded list
13 | * -> Maybe pull https://plugins.jenkins.io/api/labels
14 | * -> Prefix topics with jenkins-?
15 | *
16 |
17 | https://material-components.github.io/material-components-web-components/demos/top-app-bar-fixed/ maybe?
18 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Plugin Self Service
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | parserOptions: {
3 | ecmaVersion: 2019,
4 | sourceType: 'module'
5 | },
6 | extends: [
7 | 'eslint:recommended',
8 | 'standard'
9 | ],
10 | env: {
11 | es6: true,
12 | browser: true
13 | },
14 | plugins: [
15 | 'svelte3',
16 | 'import'
17 | ],
18 | overrides: [
19 | {
20 | files: ['*.svelte'],
21 | processor: 'svelte3/svelte3',
22 | rules: {
23 | 'import/first': 0,
24 | 'import/no-duplicates': 0,
25 | 'import/no-mutable-exports': 0,
26 | 'import/no-unresolved': 0,
27 | 'no-multiple-empty-lines': 0
28 | }
29 | }
30 | ],
31 | rules: {
32 | semi: ['error', 'always']
33 | },
34 | settings: {
35 | // ...
36 | }
37 | };
38 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | #!make
2 | .DEFAULT_GOAL := build
3 |
4 | ifndef REGISTRY
5 | override REGISTRY = halkeye
6 | endif
7 | NAME := $(shell basename $(CURDIR))
8 | VERSION := latest
9 | NAME_VERSION := $(NAME):$(VERSION)
10 | TAGNAME := $(REGISTRY)/$(NAME_VERSION)
11 |
12 | .PHONY: build
13 | build: ## Build docker image
14 | docker build -t $(TAGNAME) .
15 |
16 | .PHONY: push
17 | push: ## push to docker hub
18 | docker push $(TAGNAME)
19 |
20 | .PHONY: push
21 | kill: ## kill the running process
22 | docker kill $(NAME)
23 |
24 | .SHELL := /bin/bash
25 | .PHONY: run
26 | run: ## run the docker hub
27 | docker run \
28 | -it \
29 | --rm \
30 | -p 3000:5000 \
31 | -e GITHUB_CLIENT_ID \
32 | -e GITHUB_CLIENT_SECRET \
33 | --name $(NAME) \
34 | $(TAGNAME)
35 |
36 | .PHONY: help
37 | help:
38 | @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
39 |
--------------------------------------------------------------------------------
/src/App.svelte:
--------------------------------------------------------------------------------
1 |
10 |
11 |
19 |
20 |
21 | Plugins Self Service
22 |
23 |
24 |
25 |
26 | {#if $hasAny}
27 |
28 |
29 | Working
30 |
31 | {/if}
32 |
33 |
34 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Archived, see https://github.com/jenkins-infra/helpdesk/issues/4175
2 |
3 | # plugins-self-service
4 |
5 | [](https://cloud.digitalocean.com/apps/new?repo=https://github.com/jenkins-infra/plugins-self-service/tree/master)
6 |
7 | Little app to manage some once in a while tasks for plugin maintainers
8 |
9 | ## Screenshots
10 |
11 | 
12 |
13 | 
14 |
15 | 
16 |
17 | ## Running
18 |
19 | ### Installing
20 |
21 | ```npm install```
22 |
23 | ### Running
24 |
25 | ```
26 | export GITHUB_CLIENT_ID=
27 | export GITHUB_CLIENT_SECRET=
28 | npm run start
29 | ```
30 |
31 | ## Development
32 |
33 | ### Installing
34 |
35 | ```npm install```
36 |
37 | ### Running
38 |
39 | ```
40 | export GITHUB_CLIENT_ID=
41 | export GITHUB_CLIENT_SECRET=
42 | npm run dev
43 | ```
44 |
--------------------------------------------------------------------------------
/public/global.css:
--------------------------------------------------------------------------------
1 | html, body {
2 | position: relative;
3 | width: 100%;
4 | height: 100%;
5 | }
6 |
7 | body {
8 | color: #333;
9 | margin: 0;
10 | padding: 0;
11 | box-sizing: border-box;
12 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
13 | }
14 |
15 | a {
16 | color: rgb(0,100,200);
17 | text-decoration: none;
18 | }
19 |
20 | a:hover {
21 | text-decoration: underline;
22 | }
23 |
24 | a:visited {
25 | color: rgb(0,80,160);
26 | }
27 |
28 | label {
29 | display: block;
30 | }
31 |
32 | input, button, select, textarea {
33 | font-family: inherit;
34 | font-size: inherit;
35 | -webkit-padding: 0.4em 0;
36 | padding: 0.4em;
37 | margin: 0 0 0.5em 0;
38 | box-sizing: border-box;
39 | border: 1px solid #ccc;
40 | border-radius: 2px;
41 | }
42 |
43 | input:disabled {
44 | color: #ccc;
45 | }
46 |
47 | button {
48 | color: #333;
49 | background-color: #f4f4f4;
50 | outline: none;
51 | }
52 |
53 | button:disabled {
54 | color: #999;
55 | }
56 |
57 | button:not(:disabled):active {
58 | background-color: #ddd;
59 | }
60 |
61 | button:focus {
62 | border-color: #666;
63 | }
64 |
--------------------------------------------------------------------------------
/bin/www:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | /**
4 | * Module dependencies.
5 | */
6 |
7 | const app = require('../index');
8 | const debug = require('debug')('a:server');
9 | const http = require('http');
10 |
11 | /**
12 | * Get port from environment and store in Express.
13 | */
14 |
15 | const port = normalizePort(process.env.PORT || '5000');
16 | app.set('port', port);
17 |
18 | /**
19 | * Create HTTP server.
20 | */
21 |
22 | const server = http.createServer(app);
23 |
24 | /**
25 | * Listen on provided port, on all network interfaces.
26 | */
27 |
28 | server.listen(port);
29 | server.on('error', onError);
30 | server.on('listening', onListening);
31 |
32 | /**
33 | * Normalize a port into a number, string, or false.
34 | */
35 |
36 | function normalizePort (val) {
37 | const port = parseInt(val, 10);
38 |
39 | if (isNaN(port)) {
40 | // named pipe
41 | return val;
42 | }
43 |
44 | if (port >= 0) {
45 | // port number
46 | return port;
47 | }
48 |
49 | return false;
50 | }
51 |
52 | /**
53 | * Event listener for HTTP server "error" event.
54 | */
55 |
56 | function onError (error) {
57 | if (error.syscall !== 'listen') {
58 | throw error;
59 | }
60 |
61 | const bind = typeof port === 'string'
62 | ? 'Pipe ' + port
63 | : 'Port ' + port;
64 |
65 | // handle specific listen errors with friendly messages
66 | switch (error.code) {
67 | case 'EACCES':
68 | console.error(bind + ' requires elevated privileges');
69 | process.exit(1);
70 | case 'EADDRINUSE':
71 | console.error(bind + ' is already in use');
72 | process.exit(1);
73 | default:
74 | throw error;
75 | }
76 | }
77 |
78 | /**
79 | * Event listener for HTTP server "listening" event.
80 | */
81 |
82 | function onListening () {
83 | const addr = server.address();
84 | const bind = typeof addr === 'string'
85 | ? 'pipe ' + addr
86 | : 'port ' + addr.port;
87 | debug('Listening on ' + bind);
88 | }
89 |
--------------------------------------------------------------------------------
/labels.yaml:
--------------------------------------------------------------------------------
1 | labels:
2 | - name: good first issue
3 | color: '7057ff'
4 | - name: hackathon
5 | color: '85f920'
6 | - name: help wanted
7 | color: '008672'
8 | - name: question
9 | color: 'D876E3'
10 | - name: wontfix
11 | color: 'FFFFFF'
12 | - name: duplicate
13 | color: 'CFD3D7'
14 | - name: bug
15 | color: 'D73A4A'
16 | - name: documentation
17 | color: '0e8a16'
18 | description: A PR that adds to documentation - used by Release Drafter
19 | - name: hacktoberfest
20 | color: 'bdff3a'
21 | description: 'Hacktoberfest. https://jenkins.io/blog/2018/10/01/hacktoberfest/'
22 | - name: feature
23 | color: '1d00ff'
24 | description: A PR that adds a feature - used by Release Drafter
25 | - name: bugfix
26 | oldname: fix
27 | color: 'c9e85c'
28 | description: A PR that fixes a bug - used by Release Drafter
29 | - name: chore
30 | color: 'c9abea'
31 | description: a PR that adds to maintenance - used by Release Drafter
32 | - name: test
33 | color: 'd6e819'
34 | description: A PR that adds to testing - used by Release Drafter
35 | - name: pinned
36 | color: '5ed5e5'
37 | description: 'Used to avoid stale[bot] marking a issue/PR stale'
38 | - name: plugin-compatibility
39 | color: '8425c4'
40 | - name: stale
41 | color: 'ffffff'
42 | description: 'Used by stale[bot] to mark a issue/PR stale'
43 | - name: skip-changelog
44 | color: 'f44271'
45 | description: A PR that is excluded from Release draft - used by Release Drafter
46 | - name: removed
47 | color: 'aa0f1c'
48 | description: A PR that removes code - used by Release Drafter
49 | - name: deprecated
50 | color: 'e2b626'
51 | description: A PR that deprecates code - used by Release Drafter
52 | - name: breaking
53 | color: '640910'
54 | description: A PR that is a breaking change - used by Release Drafter
55 | - name: dependencies
56 | color: '0366d6'
57 | description: A PR that updates dependencies - used by Release Drafter
58 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "plugins-self-service",
3 | "description": "Plugins Self Service",
4 | "private": true,
5 | "license": "MIT",
6 | "version": "1.0.0",
7 | "scripts": {
8 | "build": "webpack-cli",
9 | "dev": "nodemon -w index.js -w graphql -w app -e js,mjs,json,graphql ./bin/www",
10 | "start": "node ./bin/www",
11 | "lint": "eslint --cache ."
12 | },
13 | "devDependencies": {
14 | "autoprefixer": "^10.2.4",
15 | "babel-loader": "^8.2.2",
16 | "clean-webpack-plugin": "^3.0.0",
17 | "css-loader": "^5.0.2",
18 | "eslint": "^7.21.0",
19 | "eslint-config-standard": "^16.0.2",
20 | "eslint-plugin-import": "^2.22.1",
21 | "eslint-plugin-node": "^11.1.0",
22 | "eslint-plugin-promise": "^4.3.1",
23 | "eslint-plugin-svelte3": "^3.1.2",
24 | "husky": "^4.3.8",
25 | "lint-staged": "^10.5.4",
26 | "mini-css-extract-plugin": "^1.3.8",
27 | "nodemon": "^2.0.7",
28 | "postcss-loader": "^5.0.0",
29 | "svelte": "^3.0.0",
30 | "svelte-loader": "^3.0.0",
31 | "svelte-preprocess": "^4.6.9",
32 | "webpack": "^5.23.0",
33 | "webpack-cli": "^4.5.0",
34 | "webpack-dev-middleware": "^4.1.0"
35 | },
36 | "dependencies": {
37 | "@material/mwc-button": "^0.20.0",
38 | "@material/mwc-circular-progress": "^0.20.0",
39 | "@material/mwc-dialog": "^0.20.0",
40 | "@material/mwc-icon-button": "^0.20.0",
41 | "@material/mwc-list": "^0.20.0",
42 | "@material/mwc-snackbar": "^0.20.0",
43 | "@material/mwc-top-app-bar": "^0.20.0",
44 | "@octokit/graphql": "^4.6.0",
45 | "@webcomponents/webcomponentsjs": "^2.5.0",
46 | "cookie-parser": "^1.4.5",
47 | "cors": "^2.8.5",
48 | "express": "^4.17.1",
49 | "express-session": "^1.17.1",
50 | "js-yaml": "^4.0.0",
51 | "morgan": "^1.10.0",
52 | "node-fetch": "^2.6.1",
53 | "passport": "^0.4.1",
54 | "passport-github2": "^0.1.12",
55 | "session-file-store": "^1.5.0",
56 | "svelte-fetch": "^0.2.0",
57 | "uuid": "^8.3.2"
58 | },
59 | "husky": {
60 | "hooks": {
61 | "pre-commit": "lint-staged"
62 | }
63 | },
64 | "lint-staged": {
65 | "*.js": "eslint --cache --fix"
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/PluginLabels.svelte:
--------------------------------------------------------------------------------
1 |
49 |
50 |
55 |
56 |
57 |
58 | {#await fetchTopics(owner, name)}
59 | ...grabbing a list labels for {name}
60 | {:then}
61 |
62 | {#each possibleTopics as topic}
63 |
64 | {topic.id}
65 | {#if topic.title}
66 | {topic.title}
67 | {/if}
68 |
69 | {/each}
70 |
71 | {:catch error}
72 | An error occurred!
73 |
74 |
75 | {error}
76 |
77 |
78 | {/await}
79 | Apply
80 | Cancel
81 |
82 |
83 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Created by https://www.toptal.com/developers/gitignore/api/node
3 | # Edit at https://www.toptal.com/developers/gitignore?templates=node
4 |
5 | ### Node ###
6 | # Logs
7 | logs
8 | *.log
9 | npm-debug.log*
10 | yarn-debug.log*
11 | yarn-error.log*
12 | lerna-debug.log*
13 |
14 | # Diagnostic reports (https://nodejs.org/api/report.html)
15 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
16 |
17 | # Runtime data
18 | pids
19 | *.pid
20 | *.seed
21 | *.pid.lock
22 |
23 | # Directory for instrumented libs generated by jscoverage/JSCover
24 | lib-cov
25 |
26 | # Coverage directory used by tools like istanbul
27 | coverage
28 | *.lcov
29 |
30 | # nyc test coverage
31 | .nyc_output
32 |
33 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
34 | .grunt
35 |
36 | # Bower dependency directory (https://bower.io/)
37 | bower_components
38 |
39 | # node-waf configuration
40 | .lock-wscript
41 |
42 | # Compiled binary addons (https://nodejs.org/api/addons.html)
43 | build/Release
44 |
45 | # Dependency directories
46 | node_modules/
47 | jspm_packages/
48 |
49 | # TypeScript v1 declaration files
50 | typings/
51 |
52 | # TypeScript cache
53 | *.tsbuildinfo
54 |
55 | # Optional npm cache directory
56 | .npm
57 |
58 | # Optional eslint cache
59 | .eslintcache
60 |
61 | # Optional stylelint cache
62 | .stylelintcache
63 |
64 | # Microbundle cache
65 | .rpt2_cache/
66 | .rts2_cache_cjs/
67 | .rts2_cache_es/
68 | .rts2_cache_umd/
69 |
70 | # Optional REPL history
71 | .node_repl_history
72 |
73 | # Output of 'npm pack'
74 | *.tgz
75 |
76 | # Yarn Integrity file
77 | .yarn-integrity
78 |
79 | # dotenv environment variables file
80 | .env
81 | .env.test
82 | .env*.local
83 |
84 | # parcel-bundler cache (https://parceljs.org/)
85 | .cache
86 | .parcel-cache
87 |
88 | # Next.js build output
89 | .next
90 |
91 | # Nuxt.js build / generate output
92 | .nuxt
93 | dist
94 |
95 | # Gatsby files
96 | .cache/
97 | # Comment in the public line in if your project uses Gatsby and not Next.js
98 | # https://nextjs.org/blog/next-9-1#public-directory-support
99 | # public
100 |
101 | # vuepress build output
102 | .vuepress/dist
103 |
104 | # Serverless directories
105 | .serverless/
106 |
107 | # FuseBox cache
108 | .fusebox/
109 |
110 | # DynamoDB Local files
111 | .dynamodb/
112 |
113 | # TernJS port file
114 | .tern-port
115 |
116 | # Stores VSCode versions used for testing VSCode extensions
117 | .vscode-test
118 |
119 | # End of https://www.toptal.com/developers/gitignore/api/node
120 | sessions/
121 | public/build/
122 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 |
2 | # Created by https://www.toptal.com/developers/gitignore/api/node
3 | # Edit at https://www.toptal.com/developers/gitignore?templates=node
4 |
5 | ### Node ###
6 | # Logs
7 | logs
8 | *.log
9 | npm-debug.log*
10 | yarn-debug.log*
11 | yarn-error.log*
12 | lerna-debug.log*
13 |
14 | # Diagnostic reports (https://nodejs.org/api/report.html)
15 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
16 |
17 | # Runtime data
18 | pids
19 | *.pid
20 | *.seed
21 | *.pid.lock
22 |
23 | # Directory for instrumented libs generated by jscoverage/JSCover
24 | lib-cov
25 |
26 | # Coverage directory used by tools like istanbul
27 | coverage
28 | *.lcov
29 |
30 | # nyc test coverage
31 | .nyc_output
32 |
33 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
34 | .grunt
35 |
36 | # Bower dependency directory (https://bower.io/)
37 | bower_components
38 |
39 | # node-waf configuration
40 | .lock-wscript
41 |
42 | # Compiled binary addons (https://nodejs.org/api/addons.html)
43 | build/Release
44 |
45 | # Dependency directories
46 | node_modules/
47 | jspm_packages/
48 |
49 | # TypeScript v1 declaration files
50 | typings/
51 |
52 | # TypeScript cache
53 | *.tsbuildinfo
54 |
55 | # Optional npm cache directory
56 | .npm
57 |
58 | # Optional eslint cache
59 | .eslintcache
60 |
61 | # Optional stylelint cache
62 | .stylelintcache
63 |
64 | # Microbundle cache
65 | .rpt2_cache/
66 | .rts2_cache_cjs/
67 | .rts2_cache_es/
68 | .rts2_cache_umd/
69 |
70 | # Optional REPL history
71 | .node_repl_history
72 |
73 | # Output of 'npm pack'
74 | *.tgz
75 |
76 | # Yarn Integrity file
77 | .yarn-integrity
78 |
79 | # dotenv environment variables file
80 | .env
81 | .env.test
82 | .env*.local
83 |
84 | # parcel-bundler cache (https://parceljs.org/)
85 | .cache
86 | .parcel-cache
87 |
88 | # Next.js build output
89 | .next
90 |
91 | # Nuxt.js build / generate output
92 | .nuxt
93 | dist
94 |
95 | # Gatsby files
96 | .cache/
97 | # Comment in the public line in if your project uses Gatsby and not Next.js
98 | # https://nextjs.org/blog/next-9-1#public-directory-support
99 | # public
100 |
101 | # vuepress build output
102 | .vuepress/dist
103 |
104 | # Serverless directories
105 | .serverless/
106 |
107 | # FuseBox cache
108 | .fusebox/
109 |
110 | # DynamoDB Local files
111 | .dynamodb/
112 |
113 | # TernJS port file
114 | .tern-port
115 |
116 | # Stores VSCode versions used for testing VSCode extensions
117 | .vscode-test
118 |
119 | # End of https://www.toptal.com/developers/gitignore/api/node
120 | sessions/
121 | public/build/
122 |
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 |
2 | # Created by https://www.toptal.com/developers/gitignore/api/node
3 | # Edit at https://www.toptal.com/developers/gitignore?templates=node
4 |
5 | ### Node ###
6 | # Logs
7 | logs
8 | *.log
9 | npm-debug.log*
10 | yarn-debug.log*
11 | yarn-error.log*
12 | lerna-debug.log*
13 |
14 | # Diagnostic reports (https://nodejs.org/api/report.html)
15 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
16 |
17 | # Runtime data
18 | pids
19 | *.pid
20 | *.seed
21 | *.pid.lock
22 |
23 | # Directory for instrumented libs generated by jscoverage/JSCover
24 | lib-cov
25 |
26 | # Coverage directory used by tools like istanbul
27 | coverage
28 | *.lcov
29 |
30 | # nyc test coverage
31 | .nyc_output
32 |
33 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
34 | .grunt
35 |
36 | # Bower dependency directory (https://bower.io/)
37 | bower_components
38 |
39 | # node-waf configuration
40 | .lock-wscript
41 |
42 | # Compiled binary addons (https://nodejs.org/api/addons.html)
43 | build/Release
44 |
45 | # Dependency directories
46 | node_modules/
47 | jspm_packages/
48 |
49 | # TypeScript v1 declaration files
50 | typings/
51 |
52 | # TypeScript cache
53 | *.tsbuildinfo
54 |
55 | # Optional npm cache directory
56 | .npm
57 |
58 | # Optional eslint cache
59 | .eslintcache
60 |
61 | # Optional stylelint cache
62 | .stylelintcache
63 |
64 | # Microbundle cache
65 | .rpt2_cache/
66 | .rts2_cache_cjs/
67 | .rts2_cache_es/
68 | .rts2_cache_umd/
69 |
70 | # Optional REPL history
71 | .node_repl_history
72 |
73 | # Output of 'npm pack'
74 | *.tgz
75 |
76 | # Yarn Integrity file
77 | .yarn-integrity
78 |
79 | # dotenv environment variables file
80 | .env
81 | .env.test
82 | .env*.local
83 |
84 | # parcel-bundler cache (https://parceljs.org/)
85 | .cache
86 | .parcel-cache
87 |
88 | # Next.js build output
89 | .next
90 |
91 | # Nuxt.js build / generate output
92 | .nuxt
93 | dist
94 |
95 | # Gatsby files
96 | .cache/
97 | # Comment in the public line in if your project uses Gatsby and not Next.js
98 | # https://nextjs.org/blog/next-9-1#public-directory-support
99 | # public
100 |
101 | # vuepress build output
102 | .vuepress/dist
103 |
104 | # Serverless directories
105 | .serverless/
106 |
107 | # FuseBox cache
108 | .fusebox/
109 |
110 | # DynamoDB Local files
111 | .dynamodb/
112 |
113 | # TernJS port file
114 | .tern-port
115 |
116 | # Stores VSCode versions used for testing VSCode extensions
117 | .vscode-test
118 |
119 | # End of https://www.toptal.com/developers/gitignore/api/node
120 | sessions/
121 | Dockerfile
122 | .git
123 | public/build/
124 |
--------------------------------------------------------------------------------
/src/RepoList.svelte:
--------------------------------------------------------------------------------
1 |
27 |
28 |
29 |
30 |
31 |
57 |
58 |
59 | {#await fetchRepos()}
60 | ...grabbing a list of plugins you have admin on
61 | {:then repos}
62 | {#each repos as repo}
63 |
68 | {/each}
69 | {#if selected && selected.type === 'githubLabels'}
70 |
71 | {/if}
72 | {#if selected && selected.type === 'pluginLabels'}
73 |
74 | {/if}
75 | {:catch error}
76 | An error occurred!
77 |
78 |
79 | {error}
80 |
81 |
82 | {/await}
83 |
84 |
85 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | // https://github.com/baileyherbert/svelte-webpack-starter/blob/master/webpack.config.ts
2 | const SveltePreprocess = require('svelte-preprocess');
3 | const Autoprefixer = require('autoprefixer');
4 | const MiniCssExtractPlugin = require('mini-css-extract-plugin');
5 | const path = require('path');
6 |
7 | const mode = process.env.NODE_ENV || 'development';
8 | const isProduction = mode === 'production';
9 | const isDevelopment = !isProduction;
10 | const sourceMapsInProduction = true;
11 |
12 | module.exports = {
13 | entry: {
14 | bundle: ['./src/main.js']
15 | },
16 | mode: isProduction ? 'production' : 'development',
17 | output: {
18 | path: path.resolve(__dirname, 'public/build'),
19 | publicPath: '/build/',
20 | filename: '[name].js',
21 | chunkFilename: '[name].[id].js'
22 | },
23 | resolve: {
24 | extensions: ['.mjs', '.js', '.ts', '.svelte'],
25 | mainFields: ['svelte', 'browser', 'module', 'main']
26 | },
27 | module: {
28 | rules: [
29 | // Rule: Svelte
30 | {
31 | test: /\.svelte$/,
32 | use: {
33 | loader: 'svelte-loader',
34 | options: {
35 | compilerOptions: {
36 | // Dev mode must be enabled for HMR to work!
37 | dev: isDevelopment
38 | },
39 | emitCss: isProduction,
40 | hotReload: isDevelopment,
41 | hotOptions: {
42 | // List of options and defaults: https://www.npmjs.com/package/svelte-loader-hot#usage
43 | noPreserveState: false,
44 | optimistic: true
45 | },
46 | preprocess: SveltePreprocess({
47 | scss: false,
48 | sass: false,
49 | postcss: {
50 | plugins: [
51 | Autoprefixer
52 | ]
53 | }
54 | })
55 | }
56 | }
57 | },
58 | // Rule: CSS
59 | {
60 | test: /\.css$/,
61 | use: [
62 | {
63 | loader: MiniCssExtractPlugin.loader
64 | },
65 | 'css-loader'
66 | ]
67 | },
68 |
69 | // Rule: TypeScript
70 | {
71 | test: /\.ts$/,
72 | use: 'ts-loader',
73 | exclude: /node_modules/
74 | }
75 | ]
76 | },
77 | devServer: {
78 | hot: true,
79 | stats: 'none',
80 | contentBase: 'public',
81 | watchContentBase: true
82 | },
83 | target: isDevelopment ? 'web' : 'browserslist',
84 | plugins: [
85 | new MiniCssExtractPlugin({
86 | filename: '[name].css'
87 | })
88 | ],
89 | devtool: isProduction && !sourceMapsInProduction ? false : 'source-map',
90 | stats: {
91 | chunks: false,
92 | chunkModules: false,
93 | modules: false,
94 | assets: true,
95 | entrypoints: false
96 | }
97 | };
98 |
--------------------------------------------------------------------------------
/src/GithubLabels.svelte:
--------------------------------------------------------------------------------
1 |
29 |
30 |
46 |
47 |
48 |
49 | {#await fetchLabels(owner, name)}
50 | ...grabbing a list labels for {name}
51 | {:then labels}
52 |
53 | {#each Object.keys(labels.newLabels).sort() as label}
54 |
55 | |
56 |
57 |
58 | {#if labels.existingLabels[label]}
59 | {labels.existingLabels[label].name || ''}
60 | {labels.existingLabels[label].description || ''}
61 | {#if labels.existingLabels[label].color}
62 | info
63 | {/if}
64 | {/if}
65 |
66 |
67 | |
68 |
69 | double_arrow
70 | |
71 |
72 |
73 |
74 | {labels.newLabels[label].name || ''}
75 | {labels.newLabels[label].description || ''}
76 | info
77 |
78 |
79 | |
80 |
81 | {/each}
82 |
83 | {:catch error}
84 | An error occurred!
85 |
86 |
87 | {error}
88 |
89 |
90 | {/await}
91 | Apply
92 | Cancel
93 |
94 |
95 |
--------------------------------------------------------------------------------
/scripts/setupTypeScript.js:
--------------------------------------------------------------------------------
1 | // @ts-check
2 |
3 | /** This script modifies the project to support TS code in .svelte files like:
4 |
5 |
8 |
9 | As well as validating the code for CI.
10 | */
11 |
12 | /** To work on this script:
13 | rm -rf test-template template && git clone sveltejs/template test-template && node scripts/setupTypeScript.js test-template
14 | */
15 |
16 | const fs = require('fs');
17 | const path = require('path');
18 | const { argv } = require('process');
19 |
20 | const projectRoot = argv[2] || path.join(__dirname, '..');
21 |
22 | // Add deps to pkg.json
23 | const packageJSON = JSON.parse(fs.readFileSync(path.join(projectRoot, 'package.json'), 'utf8'));
24 | packageJSON.devDependencies = Object.assign(packageJSON.devDependencies, {
25 | 'svelte-check': '^1.0.0',
26 | 'svelte-preprocess': '^4.0.0',
27 | '@rollup/plugin-typescript': '^8.0.0',
28 | typescript: '^4.0.0',
29 | tslib: '^2.0.0',
30 | '@tsconfig/svelte': '^1.0.0'
31 | });
32 |
33 | // Add script for checking
34 | packageJSON.scripts = Object.assign(packageJSON.scripts, {
35 | validate: 'svelte-check'
36 | });
37 |
38 | // Write the package JSON
39 | fs.writeFileSync(path.join(projectRoot, 'package.json'), JSON.stringify(packageJSON, null, ' '));
40 |
41 | // mv src/main.js to main.ts - note, we need to edit rollup.config.js for this too
42 | const beforeMainJSPath = path.join(projectRoot, 'src', 'main.js');
43 | const afterMainTSPath = path.join(projectRoot, 'src', 'main.ts');
44 | fs.renameSync(beforeMainJSPath, afterMainTSPath);
45 |
46 | // Switch the app.svelte file to use TS
47 | const appSveltePath = path.join(projectRoot, 'src', 'App.svelte');
48 | let appFile = fs.readFileSync(appSveltePath, 'utf8');
49 | appFile = appFile.replace('