Skip to content

Commit

Permalink
Add stage to Signed API (#156)
Browse files Browse the repository at this point in the history
* Add stage to Signed API

* Add version field to signed API

* Fix tests
  • Loading branch information
Siegrift authored Dec 6, 2023
1 parent b1e8d27 commit c4fb655
Show file tree
Hide file tree
Showing 10 changed files with 42 additions and 14 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,4 @@ RUN addgroup -S deployed-api && \
USER deployed-api

COPY --chown=deployed-api:deployed-api --from=deployed-api /app/deployed-api .
ENTRYPOINT ["node", "dist/index.js"]
ENTRYPOINT ["node", "dist/src/index.js"]
3 changes: 1 addition & 2 deletions packages/airnode-feed/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -347,8 +347,7 @@ lowercase alphanumeric characters and hyphens.
## Versioning and release

Airnode feed uses [semantic versioning](https://semver.org/). The version is specified in the `package.json` file. The
package is not published to NPM, but instead dockerized and published to Docker Hub. The image is called
[api3/airnode-feed](https://hub.docker.com/r/api3/airnode-feed).
package is not published to NPM, but instead dockerized and published to Docker Hub.

To release a new version:

Expand Down
8 changes: 4 additions & 4 deletions packages/airnode-feed/src/validation/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import dotenv from 'dotenv';
import { configSchema } from './schema';
import { interpolateSecrets, parseSecrets } from './utils';

// When Airnode feed is built the "/dist" file contains "src" folder and "package.json" and the config is expected to be
// located next to the "/dist" folder. When run in development, the config is expected to be located next to the "src"
// folder (one less import level). We resolve the config by CWD as a workaround. Since the Airnode feed is dockerized,
// this is hidden from the user.
// When Airnode feed is built, the "/dist" file contains "src" folder and "package.json" and the config is expected to
// be located next to the "/dist" folder. When run in development, the config is expected to be located next to the
// "src" folder (one less import level). We resolve the config by CWD as a workaround. Since the Airnode feed is
// dockerized, this is hidden from the user.
const getConfigPath = () => join(cwd(), './config');

export const loadRawConfig = () => JSON.parse(fs.readFileSync(join(getConfigPath(), 'airnode-feed.json'), 'utf8'));
Expand Down
13 changes: 11 additions & 2 deletions packages/api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,16 @@ or
"allowedAirnodes": ["0xB47E3D8734780430ee6EfeF3c5407090601Dcd15"]
```

##### `stage`

An identifier of the deployment stage. This is used to distinguish between different deployments of Signed API, for
example `dev`, `staging` or `production`. The stage value can have 256 characters at maximum and can only include
lowercase alphanumeric characters and hyphens.

##### `version`

The version specified in the config must match the version of the Signed API at deployment time.

## API

The API provides the following endpoints:
Expand All @@ -224,8 +234,7 @@ The API provides the following endpoints:
## Versioning and release

Signed API uses [semantic versioning](https://semver.org/). The version is specified in the `package.json` file. The
package is not published to NPM, but instead dockerized and published to Docker Hub. The image is called
[api3/signed-api](https://hub.docker.com/r/api3/signed-api).
package is not published to NPM, but instead dockerized and published to Docker Hub.

To release a new version:

Expand Down
4 changes: 3 additions & 1 deletion packages/api/config/signed-api.example.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,7 @@
"delaySeconds": 15
}
],
"allowedAirnodes": ["0xbF3137b0a7574563a23a8fC8badC6537F98197CC"]
"allowedAirnodes": ["0xbF3137b0a7574563a23a8fC8badC6537F98197CC"],
"stage": "local",
"version": "0.1.0"
}
2 changes: 1 addition & 1 deletion packages/api/deployment/cloudformation-template.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"EntryPoint": [
"/bin/sh",
"-c",
"wget -O - <SIGNED_API_CONFIGURATION_URL> >> ./config/signed-api.json && node dist/index.js"
"wget -O - <SIGNED_API_CONFIGURATION_URL> >> ./config/signed-api.json && node dist/src/index.js"
],
"PortMappings": [
{
Expand Down
2 changes: 1 addition & 1 deletion packages/api/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "api",
"version": "1.0.0",
"version": "0.1.0",
"engines": {
"node": "^18.18.2",
"pnpm": "^8.11.0"
Expand Down
12 changes: 11 additions & 1 deletion packages/api/src/config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { readFileSync } from 'node:fs';
import { join } from 'node:path';
import { cwd } from 'node:process';

import { go } from '@api3/promise-utils';
import { S3 } from '@aws-sdk/client-s3';
Expand All @@ -22,12 +23,21 @@ export const fetchAndCacheConfig = async (): Promise<Config> => {
return config;
};

// When Signed API is built, the "/dist" file contains "src" folder and "package.json" and the config is expected to be
// located next to the "/dist" folder. When run in development, the config is expected to be located next to the "src"
// folder (one less import level). We resolve the config by CWD as a workaround. Since the Signed API is dockerized,
// this is hidden from the user.
const getConfigPath = () => join(cwd(), './config');

export const loadConfigFromFilesystem = () =>
JSON.parse(readFileSync(join(getConfigPath(), 'signed-api.json'), 'utf8'));

const fetchConfig = async (): Promise<any> => {
const env = loadEnv();
const source = env.CONFIG_SOURCE;
switch (source) {
case 'local': {
return JSON.parse(readFileSync(join(__dirname, '../config/signed-api.json'), 'utf8'));
return loadConfigFromFilesystem();
}
case 'aws-s3': {
return fetchConfigFromS3();
Expand Down
6 changes: 6 additions & 0 deletions packages/api/src/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { type LogFormat, logFormatOptions, logLevelOptions, type LogLevel } from
import { uniqBy } from 'lodash';
import { z } from 'zod';

import packageJson from '../package.json';

export const evmAddressSchema = z.string().regex(/^0x[\dA-Fa-f]{40}$/, 'Must be a valid EVM address');

export const evmIdSchema = z.string().regex(/^0x[\dA-Fa-f]{64}$/, 'Must be a valid EVM ID');
Expand Down Expand Up @@ -35,6 +37,10 @@ export const configSchema = z.strictObject({
endpoints: endpointsSchema,
cache: cacheSchema.optional(),
allowedAirnodes: allowedAirnodesSchema,
stage: z
.string()
.regex(/^[\da-z-]{1,256}$/, 'Only lowercase letters, numbers and hyphens are allowed (max 256 characters)'),
version: z.string().refine((version) => version === packageJson.version, 'Invalid Signed API version'),
});

export type Config = z.infer<typeof configSchema>;
Expand Down
4 changes: 3 additions & 1 deletion packages/e2e/src/signed-api/signed-api.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,7 @@
"delaySeconds": 10
}
],
"allowedAirnodes": ["0xbF3137b0a7574563a23a8fC8badC6537F98197CC"]
"allowedAirnodes": ["0xbF3137b0a7574563a23a8fC8badC6537F98197CC"],
"stage": "e2e-test",
"version": "0.1.0"
}

0 comments on commit c4fb655

Please sign in to comment.