Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci: introduce semantic versioning #97

Draft
wants to merge 38 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
c67cb52
refactor: undo unnecessary changes
daniel-mader Jul 9, 2024
125ef55
docs: list all config values
daniel-mader Jul 9, 2024
aac66d0
refactor: rename config file
daniel-mader Jul 9, 2024
66700a8
refactor: remove example files from docker image
daniel-mader Jul 9, 2024
ccacd74
refactor: merge config files
daniel-mader Jul 10, 2024
7094ee8
refactor: update .dockerignore to include all Dockerfiles and .env files
daniel-mader Jul 10, 2024
4352cd6
WIP: migrate from config macro to config function
daniel-mader Jul 10, 2024
f282fb1
refactor: configs for `log_format` and `event_store`
daniel-mader Jul 11, 2024
d47c590
refactor: remove unused macros calls
daniel-mader Jul 11, 2024
5ba695f
refactor: migrate `url` config
daniel-mader Jul 12, 2024
3f40a05
refactor: `secret_manager` config
daniel-mader Jul 12, 2024
3763a04
refactor: `credential_configurations` config
daniel-mader Jul 12, 2024
29d2f18
refactor: rename `DidMethodOptions`, add config for `signing_algorith…
daniel-mader Jul 12, 2024
6053fc8
refactor: determine default DID method
daniel-mader Jul 12, 2024
18800f4
refactor: remove comments, load env variables
daniel-mader Jul 12, 2024
0949573
WIP: refactor `event_publishers` config
daniel-mader Jul 12, 2024
2dac2f3
refactor: remove `metadata`
daniel-mader Jul 15, 2024
6be5483
refactor: remove `config!` macro
daniel-mader Jul 15, 2024
b9106d7
refactor: rename `config_2` to `config`
daniel-mader Jul 15, 2024
f572d4a
chore: change example logo, disable `event_publisher`, respect `defau…
daniel-mader Jul 16, 2024
e63e3a1
chore: resolve clippy issues
daniel-mader Jul 17, 2024
5bf7de4
refactor: remove `set_metadata_configuration`
daniel-mader Jul 17, 2024
d62f3b8
refactor: remove `TEST_METADATA`
daniel-mader Jul 18, 2024
7ff29a2
WIP
nanderstabel Jul 22, 2024
f0610aa
test: fix tests
nanderstabel Jul 23, 2024
0e96942
ci: update docker-compose
nanderstabel Jul 23, 2024
dd630e0
fix: replace `localhost` with container name
daniel-mader Jul 23, 2024
3295f41
refactor: clean up code
nanderstabel Jul 23, 2024
deabbcc
chore: fix unused import
nanderstabel Jul 23, 2024
68d181c
feat: install `@commitlint` and `semantic-release`
daniel-mader Jul 23, 2024
966ce97
feat: check PR title with `commitlint`
daniel-mader Jul 24, 2024
f8581c8
refactor: move `commitlint` to separate workflow
daniel-mader Jul 24, 2024
056d18c
refactor: only check PR title for `dev`
daniel-mader Jul 24, 2024
3d04109
chore: disable `types` (temporarily)
daniel-mader Jul 24, 2024
a07f38a
ci: add default `semantic-release` workflow (for Node projects)
daniel-mader Jul 24, 2024
54a9bd3
docs: add reference to "Twelve-Factor App"
daniel-mader Jul 24, 2024
af1ce93
docs: add badge for DockerHub pulls
daniel-mader Jul 24, 2024
ea1800c
Merge branch 'refactor/config' into ci/versioning
daniel-mader Jul 24, 2024
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
3 changes: 2 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
Dockerfile
**/Dockerfile
**/target
**/.git
**/*.env
22 changes: 9 additions & 13 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
AGENT_CONFIG_LOG_FORMAT=json
AGENT_CONFIG_EVENT_STORE=postgres
AGENT_CONFIG_URL=https://my-domain.example.org
AGENT_APPLICATION_ENABLE_CORS=false
AGENT_SECRET_MANAGER_STRONGHOLD_PATH="test.stronghold"
AGENT_SECRET_MANAGER_STRONGHOLD_PASSWORD="secure_password"
AGENT_SECRET_MANAGER_ISSUER_DID="did:key:z6Mkv5KkqNHuR6bPVT8fud3m9JaHBSEjEmiLp7HuGAwtbkk6"
AGENT_SECRET_MANAGER_ISSUER_FRAGMENT="key-0"
AGENT_SECRET_MANAGER_ISSUER_KEY_ID="9O66nzWqYYy1LmmiOudOlh2SMIaUWoTS"
AGENT_CONFIG_DID_METHOD_WEB_ENABLED=false
AGENT_STORE_DB_CONNECTION_STRING=postgresql://demo_user:demo_pass@localhost:5432/demo
AGENT_API_REST_EXTERNAL_SERVER_RESPONSE_TIMEOUT_MS=500
AGENT_CONFIG_DOMAIN_LINKAGE_ENABLED=false
AGENT__LOG_FORMAT=text
AGENT__EVENT_STORE__TYPE=postgres
AGENT__EVENT_STORE__CONNECTION_STRING="postgresql://demo_user:demo_pass@cqrs-postgres-db:5432/demo"

AGENT__SECRET_MANAGER__STRONGHOLD_PATH="agent_secret_manager/tests/res/test.stronghold"
AGENT__SECRET_MANAGER__STRONGHOLD_PASSWORD="secure_password"
AGENT__SECRET_MANAGER__ISSUER_KEY_ID="9O66nzWqYYy1LmmiOudOlh2SMIaUWoTS"
AGENT__SECRET_MANAGER__ISSUER_DID="did:iota:rms:0x42ad588322e58b3c07aa39e4948d021ee17ecb5747915e9e1f35f028d7ecaf90"
AGENT__SECRET_MANAGER__ISSUER_FRAGMENT="bQKQRzaop7CgEvqVq8UlgLGsdF-R-hnLFkKFZqW2VN0"
26 changes: 26 additions & 0 deletions .github/workflows/lint-pr-title.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Lint PR title

on:
pull_request:
branches: ["dev"]
# https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request
# types: [opened, synchronize, reopened, edited]

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: "lts/*"

- run: npm ci

- run: echo $TITLE | npx commitlint
env:
# Security: we mitigate script injections by using an intermediate environment variable
# https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-an-intermediate-environment-variable
TITLE: ${{ github.event.pull_request.title }}
39 changes: 39 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# https://github.com/semantic-release/semantic-release/blob/master/docs/recipes/ci-configurations/github-actions.md
name: Release

on:
workflow_dispatch:
# push:
# branches:
# - main

permissions:
contents: read # for checkout

jobs:
release:
name: Release
runs-on: ubuntu-latest
permissions:
contents: write # to be able to publish a GitHub release
issues: write # to be able to comment on released issues
pull-requests: write # to be able to comment on released pull requests
id-token: write # to enable use of OIDC for npm provenance
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: "lts/*"
- name: Install dependencies
run: npm clean-install
- name: Verify the integrity of provenance attestations and registry signatures for installed dependencies
run: npm audit signatures
- name: Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: npx semantic-release
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@

**/*.env
!**/.env.example

node_modules
39 changes: 31 additions & 8 deletions Cargo.lock

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

14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# SSI Agent

[![semantic-release: angular](https://img.shields.io/badge/semantic--release-angular-e10079?logo=semantic-release)](https://github.com/semantic-release/semantic-release)
[![GitHub License](https://img.shields.io/github/license/impierce/ssi-agent)](https://github.com/impierce/ssi-agent/blob/HEAD/LICENSE)
[![Docker Pulls](https://img.shields.io/docker/pulls/impiercetechnologies/ssi-agent)](https://hub.docker.com/r/impiercetechnologies/ssi-agent)

<!-- This is a playful reference to the "Twelve-Factor App" conventions that we try to follow. -->

[![twelve-factor-app](https://img.shields.io/badge/factors-twelve-blue)](https://12factor.net)

---

## API specification

[Follow these instructions](./agent_api_rest/README.md) to inspect the REST API.
Expand All @@ -8,6 +18,10 @@

Build and run the **SSI Agent** in a local Docker environment following [these steps](./agent_application/docker/README.md).

## Configuration

All configuration options are documented [here](./agent_application/CONFIGURATION.md).

## Breaking changes

From time to time breaking changes can occur. Please make sure you read the [CHANGELOG](./CHANGELOG.md) before updating.
Expand Down
2 changes: 1 addition & 1 deletion agent_api_rest/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Browse to http://localhost:9090

### CORS

If you want to access UniCore's API from a browser, you can set the `AGENT_APPLICATION_ENABLE_CORS` environment variable to `true`. This will enable a permissive CORS policy (allow all).
If you want to access UniCore's API from a browser, you can set the `AGENT__CORS_ENABLED` environment variable to `true`. This will enable a permissive CORS policy (allow all).

## Usage
Below we describe a typical usage of the REST API for UniCore.
Expand Down
48 changes: 18 additions & 30 deletions agent_api_rest/src/issuance/credential_issuer/credential.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use agent_issuance::{
state::{IssuanceState, SERVER_CONFIG_ID},
};
use agent_shared::{
config,
config::config,
handlers::{command_handler, query_handler},
};
use axum::{
Expand All @@ -24,7 +24,7 @@ use serde_json::json;
use tokio::time::sleep;
use tracing::{error, info};

const DEFAULT_EXTERNAL_SERVER_RESPONSE_TIMEOUT_MS: u128 = 1000;
const DEFAULT_EXTERNAL_SERVER_RESPONSE_TIMEOUT_MS: u64 = 1000;
const POLLING_INTERVAL_MS: u64 = 100;

#[axum_macros::debug_handler]
Expand Down Expand Up @@ -64,9 +64,8 @@ pub(crate) async fn credential(
StatusCode::INTERNAL_SERVER_ERROR.into_response();
};

let timeout = config!("external_server_response_timeout_ms", String)
.ok()
.and_then(|external_server_response_timeout_ms| external_server_response_timeout_ms.parse().ok())
let timeout = config()
.external_server_response_timeout_ms
.unwrap_or(DEFAULT_EXTERNAL_SERVER_RESPONSE_TIMEOUT_MS);
let start_time = Instant::now();

Expand All @@ -76,7 +75,7 @@ pub(crate) async fn credential(
match query_handler(&offer_id, &state.query.offer).await {
// When the Offer does not include the credential id's yet, wait for the external server to provide them.
Ok(Some(OfferView { credential_ids, .. })) if credential_ids.is_empty() => {
if start_time.elapsed().as_millis() <= timeout {
if start_time.elapsed().as_millis() <= timeout.into() {
sleep(Duration::from_millis(POLLING_INTERVAL_MS)).await;
} else {
error!("timeout failure");
Expand Down Expand Up @@ -142,7 +141,6 @@ pub(crate) async fn credential(

#[cfg(test)]
mod tests {
use agent_shared::metadata::{load_metadata, set_metadata_configuration};
use std::sync::Arc;

use crate::{
Expand All @@ -156,8 +154,9 @@ mod tests {
use super::*;
use crate::issuance::credentials::tests::credentials;
use crate::API_VERSION;
use agent_event_publisher_http::{EventPublisherHttp, TEST_EVENT_PUBLISHER_HTTP_CONFIG};
use agent_event_publisher_http::EventPublisherHttp;
use agent_issuance::{offer::event::OfferEvent, startup_commands::startup_commands, state::initialize};
use agent_shared::config::{set_config, Events};
use agent_store::{in_memory, EventPublisher};
use agent_verification::services::test_utils::test_verification_services;
use axum::{
Expand All @@ -181,7 +180,7 @@ mod tests {
&self,
app: Arc<Mutex<Option<Router>>>,
is_self_signed: bool,
delay: u128,
delay: u64,
);
}

Expand All @@ -193,7 +192,7 @@ mod tests {
&self,
app: Arc<Mutex<Option<Router>>>,
is_self_signed: bool,
delay: u128,
delay: u64,
) {
Mock::given(method("POST"))
.and(path("/ssi-events-subscriber"))
Expand Down Expand Up @@ -234,7 +233,7 @@ mod tests {
}
};

std::thread::sleep(Duration::from_millis(delay.try_into().unwrap()));
std::thread::sleep(Duration::from_millis(delay));

// Sends the `CredentialsRequest` to the `credentials` endpoint.
app_clone
Expand Down Expand Up @@ -275,30 +274,19 @@ mod tests {
async fn test_credential_endpoint(
#[case] with_external_server: bool,
#[case] is_self_signed: bool,
#[case] delay: u128,
#[case] delay: u64,
) {
set_metadata_configuration("did:key");

let (external_server, issuance_event_publishers, verification_event_publishers) = if with_external_server {
let external_server = MockServer::start().await;

let target_url = format!("{}/ssi-events-subscriber", &external_server.uri());

TEST_EVENT_PUBLISHER_HTTP_CONFIG.lock().unwrap().replace(
serde_yaml::from_str(&format!(
r#"
target_url: &target_url {target_url}

offer: {{
target_url: *target_url,
target_events: [
CredentialRequestVerified
]
}}
"#,
))
.unwrap(),
);
set_config().enable_event_publisher_http();
set_config().set_event_publisher_http_target_url(target_url.clone());
set_config().set_event_publisher_http_target_events(Events {
offer: vec![agent_shared::config::OfferEvent::CredentialRequestVerified],
..Default::default()
});

(
Some(external_server),
Expand All @@ -312,7 +300,7 @@ mod tests {
let issuance_state = in_memory::issuance_state(issuance_event_publishers).await;
let verification_state =
in_memory::verification_state(test_verification_services(), verification_event_publishers).await;
initialize(&issuance_state, startup_commands(BASE_URL.clone(), &load_metadata())).await;
initialize(&issuance_state, startup_commands(BASE_URL.clone())).await;

let mut app = app((issuance_state, verification_state));

Expand Down
Loading