Skip to content

Commit

Permalink
Base implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
opaoz committed Feb 11, 2024
1 parent bbee7b8 commit c85da36
Show file tree
Hide file tree
Showing 9 changed files with 920 additions and 0 deletions.
48 changes: 48 additions & 0 deletions .github/workflows/test-myself.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Test `query-postgresql` action
on:
push:
branches:
- main

env:
PG_USER: postgres
PG_PWD: mypassword
PG_DB: postgres
PG_HOST: '127.0.0.1'
PG_PORT: 5432

jobs:
test-query:
runs-on: [ "ubuntu-latest" ]
services:
postgres:
image: postgres
env:
POSTGRES_PASSWORD: ${{ env.PG_PWD }}
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Simple query
id: query
uses: ./ # Uses an action in the root directory
with:
query: |
select true as result
host: ${{ env.PG_HOST }}
port: ${{ env.PG_PORT }}
username: ${{ env.PG_USER }}
password: ${{ env.PG_PWD }}
db: ${{ env.PG_DB }}
ssl: 'false'
- name: Test 1
run: |
echo "Expecting ['1.3.0']"
echo "${{ steps.query.outputs.result }}"
echo "${{ steps.query.outputs.count }}"
test "${{ steps.query.outputs.count }}" == "1"
test "${{ steps.query.outputs.result }}" == "[1.3.0]"
132 changes: 132 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# Snowpack dependency directory (https://snowpack.dev/)
web_modules/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional stylelint cache
.stylelintcache

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local

# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache

# Next.js build output
.next
out

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public

# vuepress build output
.vuepress/dist

# vuepress v2.x temp and cache directory
.temp
.cache

# Docusaurus cache and generated files
.docusaurus

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TernJS port file
.tern-port

# Stores VSCode versions used for testing VSCode extensions
.vscode-test

# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*

.idea
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v20
41 changes: 41 additions & 0 deletions action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: "Query to PostgreSQL"
description: Make query to PostgreSQL and return JSON
author: Vladimir Levin
branding:
icon: code
color: purple
inputs:
query:
description: 'SQL query'
required: true
host:
description: 'PostgreSQL host'
required: true
db:
description: 'PostgreSQL db'
required: true
port:
description: 'PostgreSQL port (default: 5432)'
required: true
default: '5432'
username:
description: 'PostgreSQL username'
required: true
password:
description: 'PostgreSQL password'
required: true
to_file:
description: "Save result to file (default: 'false')"
ssl:
description: "SSL enabled (default: 'true')"
default: 'true'
from_file:
description: "Read query from file (default: 'false')"
outputs:
result: # id of output
description: PostgreSQL response
count:
description: Rows count
runs:
using: 'node20'
main: 'action/index.js'
45 changes: 45 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"name": "query-postgresql",
"version": "1.0.0",
"description": "Make query to PostgreSQL and return JSON",
"main": "action/index.js",
"scripts": {
"test": "yarn build && node ./action/index.js",
"build": "yarn clean && tsc --project ./tsconfig.json",
"clean": "rimraf -- action",
"release": "yarn clean && ncc build -m src/index.ts -o action --license LICENSE"
},
"repository": {
"type": "git",
"url": "git+https://github.com/yakubique/query-postgresql.git"
},
"keywords": [
"npm",
"github",
"action",
"versions"
],
"author": "Vladimir <opa-oz>",
"license": "MIT",
"bugs": {
"url": "https://github.com/yakubique/query-postgresql/issues"
},
"homepage": "https://github.com/yakubique/query-postgresql#readme",
"dependencies": {
"@actions/core": "^1.10.1",
"lodash.difference": "^4.5.0",
"lodash.differenceby": "^4.8.0",
"lodash.orderby": "^4.6.0",
"pg": "^8.11.3"
},
"devDependencies": {
"@types/lodash.difference": "^4.5.9",
"@types/lodash.differenceby": "^4.8.9",
"@types/lodash.orderby": "^4.6.9",
"@types/node": "^20.11.1",
"@types/pg": "^8.11.0",
"@vercel/ncc": "^0.38.1",
"rimraf": "^5.0.5",
"typescript": "^5.3.3"
}
}
55 changes: 55 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import * as core from '@actions/core';
import { ActionInputs, getInputs } from './io-helper';
import { Client } from 'pg';

enum Outputs {
result = 'result',
count = 'count'
}

function setOutputs(response: any, log?: boolean) {
let message = '';
for (const key in Outputs) {
const field: string = (Outputs as any)[key];
if (log) {
message += `\n ${field}: ${JSON.stringify(response[field])}`;
}
core.setOutput(field, response[field]);
}

if (log) {
core.info('Outputs:' + message);
}
}

(async function run() {
let client;

try {
const inputs: ActionInputs = getInputs();
const query = inputs.query;

client = new Client({
user: inputs.username,
password: inputs.password,
host: inputs.host,
database: inputs.db,
port: inputs.port,
ssl: inputs.ssl,
})
await client.connect()

const res = await client.query(query)

setOutputs({
result: res.rows,
count: res.rowCount,
})

core.info('Success!');
} catch (err: any) {
core.setFailed(err.message);
} finally {
await client?.end()
}
})();
64 changes: 64 additions & 0 deletions src/io-helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import * as core from '@actions/core';
import { InputOptions } from '@actions/core';

enum Inputs {
Query = 'query',
Host = 'host',
Port = 'port',
Database = 'db',
Username = 'username',
Password = 'password',
ToFile = 'to_file',
FromFile = 'from_file',
SSL = 'ssl',
}

function isBlank(value: any): boolean {
return value === null || value === undefined || (value.length !== undefined && value.length === 0);
}

export function isNotBlank(value: any): boolean {
return value !== null && value !== undefined && (value.length === undefined || value.length > 0);
}

export function getBooleanInput(name: string, options?: InputOptions): boolean {
const value = core.getInput(name, options);
return isNotBlank(value) &&
['y', 'yes', 't', 'true', 'e', 'enable', 'enabled', 'on', 'ok', '1']
.includes(value.trim().toLowerCase());
}

export interface ActionInputs {
query: string;
host: string;
db: string;
port: number;
username: string;
password: string;
toFile: boolean;
fromFile: boolean;
ssl: boolean;
}

export function getInputs(): ActionInputs {
const result: ActionInputs | any = {};

result.query = `${core.getInput(Inputs.Query, { required: true })}`
result.host = `${core.getInput(Inputs.Host, { required: true })}`
result.db = `${core.getInput(Inputs.Database, { required: true })}`
result.username = `${core.getInput(Inputs.Username, { required: true })}`
result.password = `${core.getInput(Inputs.Password, { required: true })}`

const port = `${core.getInput(Inputs.Port, { required: false })}`
if (isBlank(port)) {
result.port = 5432
} else {
result.prot = parseInt(port, 10)
}

result.toFile = getBooleanInput(Inputs.ToFile, { required: false })
result.fromFile = getBooleanInput(Inputs.FromFile, { required: false })
result.ssl = getBooleanInput(Inputs.SSL, { required: false })

return result;
}
Loading

0 comments on commit c85da36

Please sign in to comment.