-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 2fa05c2
Showing
55 changed files
with
24,956 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# EditorConfig is multi-language & growing, see: https://EditorConfig.org | ||
|
||
[*.{kt,kts}] | ||
indent_size=2 |
Validating CODEOWNERS rules …
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
## code changes will send PR to following users | ||
* @sukolenvo | ||
* @vyshane |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
name: Update Gradle Wrapper | ||
|
||
on: | ||
workflow_dispatch: | ||
schedule: | ||
- cron: "15 21 * * *" | ||
|
||
jobs: | ||
update-gradle-wrapper: | ||
runs-on: self-hosted | ||
|
||
steps: | ||
- uses: actions/checkout@v3 | ||
|
||
- name: Update Gradle Wrapper | ||
uses: gradle-update/update-gradle-wrapper-action@v1 | ||
with: | ||
reviewers: sukolenvo |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
on: | ||
issue_comment: | ||
pull_request_review_comment: | ||
pull_request_review: | ||
pull_request: | ||
types: | ||
- opened | ||
- edited | ||
push: | ||
|
||
jobs: | ||
pr_commented: | ||
name: PR comment | ||
runs-on: self-hosted | ||
steps: | ||
- uses: actions/github-script@v6 | ||
with: | ||
script: | | ||
async function processPullRequest(github, owner, repo, pull_number) { | ||
const pr = await github.rest.pulls.get({ | ||
owner, | ||
repo, | ||
pull_number | ||
}) | ||
if (pr.status !== 200) { | ||
throw "Failed to load pr: " + pr | ||
} | ||
var comments = [] | ||
comments.push(pr.data.body) | ||
const issueComments = await github.paginate(github.rest.issues.listComments.endpoint.merge({ | ||
owner, | ||
repo, | ||
issue_number: pull_number | ||
})) | ||
comments.push(...issueComments.map(comment => comment.body)) | ||
const prComments = await github.paginate(github.rest.pulls.listReviewComments.endpoint.merge({ | ||
owner, | ||
repo, | ||
pull_number | ||
})) | ||
comments.push(...prComments.map(comment => comment.body)) | ||
const prReviews = await github.paginate(github.rest.pulls.listReviews.endpoint.merge({ | ||
owner, | ||
repo, | ||
pull_number | ||
})) | ||
comments.push(...prReviews.map(comment => comment.body)) | ||
var openTasks = [] | ||
var closedTasks = [] | ||
comments | ||
.filter(comment => comment !== null) | ||
.filter(comment => comment !== undefined) | ||
.flatMap(comment => comment.split("\n")) | ||
.map(line => line.trim()) | ||
.filter(line => line.length > 0) | ||
.forEach(line => { | ||
if (line.startsWith("- [ ]")) { | ||
openTasks.push(line.substring(5).trim()) | ||
} else if (line.startsWith("- [x]")) { | ||
closedTasks.push(line.substring(5).trim()) | ||
} | ||
}) | ||
var state = { | ||
state: "success", | ||
description: "No tasks in this PR" | ||
} | ||
if (openTasks.length === 1) { | ||
state.state = "failure" | ||
state.description = "Task is not completed: '" + openTasks[0] + "'" | ||
} else if (openTasks.length > 1) { | ||
state.state = "failure" | ||
state.description = openTasks.length + " open task(s)" | ||
} else if (openTasks.length === 0) { | ||
if (closedTasks.length > 0) { | ||
state.description = closedTasks.length + " tasks closed" | ||
} | ||
} | ||
state.description = state.description.substring(0, 139) | ||
await github.rest.repos.createCommitStatus({ | ||
...state, | ||
owner, | ||
repo, | ||
sha: pr.data.head.sha, | ||
context: "pr-tasks-workflow" | ||
}) | ||
} | ||
if (context.eventName === "issue_comment" && context.payload.issue.pull_request === undefined) { | ||
console.log("Issue comment is ignored") | ||
return | ||
} | ||
if (context.eventName === "push") { | ||
const result = await github.rest.repos.listPullRequestsAssociatedWithCommit({ | ||
owner: context.payload.repository.owner.name, | ||
repo: context.payload.repository.name, | ||
commit_sha: context.payload.head_commit.id | ||
}) | ||
if (result.status !== 200) { | ||
throw "Failed to PRs for commit: " + result | ||
} | ||
result.data.forEach(pr => { | ||
processPullRequest(github, context.issue.owner, context.issue.repo, pr.number) | ||
}) | ||
} else { | ||
processPullRequest(github, context.issue.owner, context.issue.repo, context.issue.number) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
name: Close inactive issues | ||
on: | ||
workflow_dispatch: | ||
schedule: | ||
- cron: "30 1 * * *" | ||
|
||
jobs: | ||
close-issues: | ||
runs-on: self-hosted | ||
permissions: | ||
issues: write | ||
pull-requests: write | ||
steps: | ||
- uses: actions/stale@v5 | ||
with: | ||
days-before-issue-stale: 30 | ||
days-before-issue-close: 14 | ||
stale-issue-label: "stale" | ||
stale-issue-message: "This issue is stale because it has been open for 30 days with no activity." | ||
close-issue-message: "This issue was closed because it has been inactive for 14 days since being marked as stale." | ||
stale-pr-message: "This PR is stale because it has been open for 5 days with no activity." | ||
close-pr-message: "This PR was closed because it has been inactive for 14 days since being marked as stale." | ||
days-before-pr-stale: 5 | ||
days-before-pr-close: 14 | ||
repo-token: ${{ secrets.GITHUB_TOKEN }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
.idea | ||
.ideaDataSources | ||
dataSources | ||
build/ | ||
src/gen/ | ||
.gradle/ | ||
gradle.properties | ||
**/.classpath | ||
**/.project | ||
**/.settings | ||
**/target | ||
**/*.iml | ||
**/*.imlt | ||
release.properties | ||
out/ | ||
**/generated/ | ||
**/*.ipr | ||
**/*.iws | ||
**/.DS_Store | ||
.gcache |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# Set JVM via `sdk use` in rootDir | ||
java=17.0.8-amzn |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
build-fast: | ||
./gradlew build -x test -x check | ||
|
||
clean: | ||
./gradlew clean | ||
|
||
test: | ||
./gradlew check test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
# WiseTime SQL Time Post Connector | ||
|
||
## About | ||
|
||
The WiseTime SQL Post Time Connector connects [WiseTime](https://wisetime.com) to SQL databases, and will automatically: | ||
|
||
* Record a new time registration in the Database, based on the provided Queries whenever a user posts time to WiseTime | ||
|
||
In order to use the WiseTime SQL Post Time Connector, you will need a [WiseTime Connect](https://wisetime.io/docs/connect/) API key. | ||
|
||
## Configuration | ||
|
||
Configuration is done through environment variables. The following configuration options are required. | ||
|
||
| Environment Variable | Description | | ||
|----------------------|-------------------------------------------------------------------------------------------------------------------------| | ||
| API_KEY | Your WiseTime Connect API Key | | ||
| JDBC_URL | The JDBC URL for your database | | ||
| DB_USER | Username to use to connect to the database | | ||
| DB_PASSWORD | Password to use to connect to the database | | ||
| NARRATIVE_PATH | Path to the narrative formatter template. This is used to provide information about posted time to be used on invoices. | | ||
| TIME_POST_SQL_PATH | Path to yaml file containing all required time posting queries | | ||
| TAG_UPSERT_PATH | The WiseTime tag upload folder, must be set to the same value as in your tag sync connector | | ||
|
||
|
||
The following configuration options are optional. | ||
|
||
| Environment Variable | Description | | ||
|-----------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | ||
| CALLER_KEY | The caller key that WiseTime should provide with post time webhook calls. The connector does not authenticate Webhook calls if not set. | | ||
| DATA_DIR | If set, the connector will use the directory as the location for storing data to keep track of the already posted time. By default, WiseTime Connector will create a temporary dir under `/tmp` as its data storage. | | ||
| RECEIVE_POSTED_TIME | If unset, this defaults to `LONG_POLL`: use long polling to fetch posted time. Optional parameters are `WEBHOOK` to start up a server to listen for posted time. `DISABLED` no handling for posted time | | ||
| WEBHOOK_PORT | The connector will listen to this port e.g. 8090, if RECEIVE_POSTED_TIME is set to `WEBHOOK`. Defaults to 8080. | | ||
| LOG_LEVEL | Define log level. Available values are: `TRACE`, `DEBUG`, `INFO`, `WARN`, `ERROR` and `OFF`. Default is `INFO`. | | ||
| TIMEZONE | The timezone to use when posting time, e.g. `Australia/Perth`. Defaults to `UTC`. | | ||
| NARRATIVE_INTERNAL_PATH | Path to the internal narrative formatter template. This is optional and can be used to provide additional information about posted time for internal use | | ||
| ACTIVITY_TYPE_MANDATORY | Are activity types mandatory for posting time? Defaults to `true` | | ||
|
||
### Post Time Queries | ||
|
||
The queries for posting time are provided by a yaml file located in `TIME_POST_SQL_PATH`. | ||
|
||
The yaml file must contain the following exactly the following 5 queries. See `examples/time_post_sql.yaml` for a complete example. | ||
|
||
#### canQueryDb | ||
A query that executes successfully when the DB connection is healthy. Should not modify the database. | ||
|
||
#### createWorklog | ||
Should insert the posted time into the database. Should accept the following parameters and doesn't have a return value. | ||
|
||
| Parameter | Description | | ||
|---------------------|-----------------------------------------------------------------------------------------------------------------------| | ||
| :matterId | Id of the matter to post to. | | ||
| :userId | Id of the user to attribute the time to. | | ||
| :activityCode | Activity code for the posted time. | | ||
| :narrative | Main narrative that can be used on invoices. | | ||
| :narrativeInternal | Optional, only set when `NARRATIVE_INTERNAL_PATH` is set. Additional information on the posted time for internal use. | | ||
| :startTime | Start time of the posted time. Uses the timezone set via `TIMEZONE`. | | ||
| :durationSecs | Total time worked in seconds. | | ||
| :chargeableTimeSecs | Billable time in seconds. | | ||
|
||
#### doesActivityCodeExist | ||
Should verify that a provided activity code exists in the database. Should a single row with arbitrary content if the code exists, or an empty set otherwise. | ||
|
||
| Parameter | Description | | ||
|---------------------|--------------------------------| | ||
| :activityCode | The activity code to verify. | | ||
|
||
#### findMatterIdByTagName | ||
Should return the matter id of the provided tag name. Should return a single row with a single value, or an empty set otherwise. | ||
|
||
| Parameter | Description | | ||
|---------------------|--------------------------------| | ||
| :tagName | The name of the tag to find. | | ||
|
||
#### findUserId | ||
Should return the user id of the provided login id or email. Should return a single row with a single value, or an empty set otherwise. | ||
|
||
| Parameter | Description | | ||
|---------------------|--------------------------------------------------------------| | ||
| :emailOrExternalId | The email or external id of the user, as set up in Wisetime. | | ||
|
||
## Running the WiseTime SQL Post Time Connector | ||
|
||
The easiest way to run the SQL Post Time Connector is using Docker. Please see the example folder for an example docker-compose.yaml and other necessary configuration files. | ||
|
||
If you are using `RECEIVE_POSTED_TIME=WEBHOOK`: Note that you need to define port forwarding in the docker run command (and similarly any docker-compose.yaml definition). If you set the webhook port other than default (8080) you must also add the WEBHOOK_PORT environment variable to match the docker ports definition. | ||
|
||
## Building | ||
|
||
To build a Docker image of the WiseTime SQL Post Time Connector, run: | ||
|
||
```text | ||
make docker | ||
``` |
Oops, something went wrong.