diff --git a/.github/workflows/auto-release-pr.yaml b/.github/workflows/auto-release-pr.yaml new file mode 100644 index 0000000..cbb705b --- /dev/null +++ b/.github/workflows/auto-release-pr.yaml @@ -0,0 +1,70 @@ +name: Auto Release PR + +on: + push: + branches: [develop] + workflow_dispatch: + +permissions: + contents: read + pull-requests: write + +concurrency: + group: auto-release-pr + cancel-in-progress: false + +jobs: + create-release-pr: + name: Create Release PR + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Fetch main branch + run: git fetch origin main + + - name: Check for existing PR + id: check-pr + run: | + PR_COUNT=$(gh pr list --base main --head develop --state open --json number --jq 'length') + echo "pr_exists=$([[ $PR_COUNT -gt 0 ]] && echo 'true' || echo 'false')" >> $GITHUB_OUTPUT + echo "::notice::Open PRs from develop to main: $PR_COUNT" + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Check for differences + id: check-diff + if: steps.check-pr.outputs.pr_exists == 'false' + run: | + DIFF_COUNT=$(git rev-list --count origin/main..origin/develop) + echo "has_changes=$([[ $DIFF_COUNT -gt 0 ]] && echo 'true' || echo 'false')" >> $GITHUB_OUTPUT + echo "commit_count=$DIFF_COUNT" >> $GITHUB_OUTPUT + echo "::notice::Commits ahead of main: $DIFF_COUNT" + + - name: Create Release PR + if: steps.check-pr.outputs.pr_exists == 'false' && steps.check-diff.outputs.has_changes == 'true' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + COMMIT_COUNT: ${{ steps.check-diff.outputs.commit_count }} + run: | + printf '%s\n' \ + "## Automatic Release PR" \ + "" \ + "This PR was automatically created after changes were pushed to develop." \ + "" \ + "**Commits:** ${COMMIT_COUNT} new commit(s)" \ + "" \ + "### Checklist" \ + "- [ ] Review all changes" \ + "- [ ] Verify CI passes" \ + "- [ ] Approve and merge when ready for production" \ + > /tmp/pr-body.md + + gh pr create \ + --base main \ + --head develop \ + --title "Release: develop -> main" \ + --body-file /tmp/pr-body.md diff --git a/prices/prices.service.ts b/prices/prices.service.ts index cb17069..fbe1c05 100644 --- a/prices/prices.service.ts +++ b/prices/prices.service.ts @@ -28,13 +28,30 @@ export class PricesService { private readonly logger = new Logger(this.constructor.name); private fetchedPrices: PriceQueryObjectArray = {}; private euroPrice: PriceQueryCurrencies = {}; + private euroPriceTimestamp: number = 0; private depsPrice: PriceQueryCurrencies = {}; + private static readonly EURO_PRICE_TTL = 60_000; // 60 seconds + constructor( private readonly positionsService: PositionsService, private readonly deps: EcosystemDepsService ) {} + private isEuroPriceStale(): boolean { + return !this.euroPrice?.usd || Date.now() - this.euroPriceTimestamp > PricesService.EURO_PRICE_TTL; + } + + private async refreshEuroPriceIfStale(): Promise { + if (this.isEuroPriceStale()) { + const fetched = await this.fetchEuroPrice(); + if (fetched) { + this.euroPrice = fetched; + this.euroPriceTimestamp = Date.now(); + } + } + } + getPrices(): ApiPriceListing { return Object.values(this.fetchedPrices); } @@ -64,8 +81,8 @@ export class PricesService { } async getDepsPrice(): Promise { - if (!this.depsPrice) this.depsPrice = await this.fetchFromEcosystemDeps(this.getDeps()); - if (!this.euroPrice) this.euroPrice = await this.fetchEuroPrice(); + if (!this.depsPrice?.usd) this.depsPrice = await this.fetchFromEcosystemDeps(this.getDeps()); + await this.refreshEuroPriceIfStale(); return { usd: Number(this.depsPrice.usd.toFixed(4)), @@ -91,7 +108,7 @@ export class PricesService { } async getEuroPrice(): Promise { - if (!this.euroPrice) this.euroPrice = await this.fetchEuroPrice(); + await this.refreshEuroPriceIfStale(); return { usd: Number(this.euroPrice.usd.toFixed(4)), @@ -205,7 +222,10 @@ export class PricesService { this.logger.debug('Updating Prices'); const euroPrice = await this.fetchEuroPrice(); - if (euroPrice) this.euroPrice = euroPrice; + if (euroPrice) { + this.euroPrice = euroPrice; + this.euroPriceTimestamp = Date.now(); + } const deps = this.getDeps(); const m = this.getMint();