Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
20 changes: 16 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"devDependencies": {
"@actions/core": "^1.11.1",
"@actions/glob": "^0.5.0",
"@types/node": "^20.17.27",
"@typescript-eslint/eslint-plugin": "^5.62.0",
"@typescript-eslint/parser": "^5.62.0",
Expand Down
12 changes: 12 additions & 0 deletions upload-algolia-index/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Upload Algolia Index

This action uploads a set of records to a specified algolia index.

```yml
- uses: graycoreio/github-actions/upload-algolia-index@main
with:
appId: ${{ secrets.ALGOLIA_APP_ID }}
apiKey: ${{ secrets.ALGOLIA_API_KEY }}
indexName: my_index_name
dir: ${{ github.workspace }}/my/index/records
```
33 changes: 33 additions & 0 deletions upload-algolia-index/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: 'Upload Algolia Index'
author: 'Graycore'
description: 'An action that uploads a set of search indices to the Algolia search engine.'

inputs:
appId:
description: 'The ID of the Algolia application.'
required: true
indexName:
description: 'The name of the Algolia index.'
required: true
apiKey:
description: 'The Algolia API key.'
required: true
dir:
description: 'The directory containing the records to upload to the index. Should be absolute.'
required: true
glob:
description: 'An optional glob pattern to select which records are uploaded.'
required: false
default: '**/*'
objectIdKey:
description: 'The field on the records that contains the unique object ID.'
required: false
default: 'id'

runs:
using: "node20"
main: dist/index.js

branding:
icon: "code"
color: "green"
75 changes: 75 additions & 0 deletions upload-algolia-index/dist/index.js

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions upload-algolia-index/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module.exports = {
clearMocks: true,
moduleFileExtensions: ['js', 'ts'],
testMatch: ['**/*.spec.ts'],
transform: {
'^.+\\.ts$': 'ts-jest'
},
verbose: true
}
153 changes: 153 additions & 0 deletions upload-algolia-index/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions upload-algolia-index/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "@graycore/github-actions-set-versions-from-root",
"version": "1.0.0",
"description": "A Github Action that sets versions in left packages from a root version.",
"main": "index.js",
"private": true,
"scripts": {
"build": "npx esbuild --outfile=dist/index.js --platform=node --bundle --minify src/index.ts && tsc --noEmit",
"test": "jest"
},
"author": "",
"license": "MIT",
"devDependencies": {
"@types/node": "^20.19.1"
},
"dependencies": {
"@algolia/client-search": "^5.29.0"
}
}
36 changes: 36 additions & 0 deletions upload-algolia-index/src/get-records.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import * as core from '@actions/core';
import * as glob from '@actions/glob';
import * as fs from 'fs/promises';

export interface Record {
objectID: string;
[k: string]: unknown
}

export async function getRecords(
dir: string,
globPattern = '**/*',
objectIdKey = 'id',
): Promise<Array<Record>> {
const globber = await glob.create(`${dir}/${globPattern}`)

let records: Array<Record> = []
for await (const path of globber.globGenerator()) {
if ((await fs.stat(path)).isFile()) {
const obj = JSON.parse(await fs.readFile(path, 'utf8'))
const objectID = obj[objectIdKey]

if (!objectID) {
core.warning(`Object ID not found for ${path} using key ${objectIdKey}`)
}

records.push({
...obj,
objectID,
})
}
}
core.notice(`Found ${records.length} records to upload.`)

return records
}
35 changes: 35 additions & 0 deletions upload-algolia-index/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import * as core from '@actions/core';
import { upload } from './upload';
import { getRecords } from './get-records';

export async function run(): Promise<void> {
try {
const appId: string = core.getInput('appId', {required: true})
const indexName: string = core.getInput('indexName', {required: true})
const apiKey: string = core.getInput('apiKey', {required: true})
const dir: string = core.getInput('dir', {required: true})
const globPattern: string = core.getInput('glob')
const objectIdKey: string = core.getInput('objectIdKey')

await upload(
appId,
indexName,
apiKey,
await getRecords(
dir,
globPattern,
objectIdKey
)
)
}
catch (error) {
if (error instanceof Error) {
core.setFailed(error.message);
}
else {
core.setFailed("Something went wrong.");
}
}
}

run();
31 changes: 31 additions & 0 deletions upload-algolia-index/src/upload.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import * as core from '@actions/core';
import { searchClient } from "@algolia/client-search";
import { Record } from './get-records';

export interface Options {
appId: string
indexName: string
apiKey: string
dir: string
globPattern?: string
objectIdKey?: string
}

export async function upload(
appId: string,
indexName: string,
apiKey: string,
records: Array<Record>
): Promise<void> {
const client = searchClient(
appId,
apiKey
);

core.debug('Beginning upload.')
await client.saveObjects({
indexName,
objects: records
});
core.debug(`Finished upload.`)
}
Loading