Deploy di Angular SPA con GitHub Actions — Environment Variables

Francesco Sciuti
Devmy
Published in
5 min readJun 21, 2020

--

In un passato articolo (non troppo remoto), mi sono occupato di come possa essere semplice eseguire il deploy di un’applicazione Angular per mezzo delle GitHub Actions:

Era rimasto però in sospeso un dettaglio non da poco, che ora (mi auguro) in poche righe proveremo a risolvere, e cioè la possibilità in fase di build di passare delle environment variables che altrimenti dovrebbero essere memorizzate in uno dei files del repository, costringendoci così a rendere insicuri, ad esempio, eventuali token (perché esposti al mondo intero).

A parte il fatto che GitHub (che è notoriamente intelligente) si sarebbe accorto di tutto ciò con molta probabilità e ci avrebbe rimproverato severamente, è chiaro che dobbiamo trovare una soluzione migliore.

Le environment variables in Angular

Facciamo un breve passo indietro però…
come gestisce Angular le environment variables?

Angular (spiegandola in soldoni) ci consente di indicarle, per mezzo di files presenti nella cartella /src/environments del nostro progetto.
A creazione del progetto sono presenti difatti 2 files:

  • environment.ts (utilizzato per la fase di sviluppo);
  • environment.prod.ts (utilizzato in fase di build di produzione del progetto).

Entrambe i files contengono un oggetto di nome environment che conterrà, come coppie chiave/valore, le nostre enviroment variables.

La cosa interessante è che sarà Angular stesso, in fase di compilazione del progetto per la produzione, a sostituire il file usato in stage (environment.ts) con quello corretto (environment.prod.ts).
Questo comportamento, tra l’altro, lo si può evincere anche dal file angular.json, nel quale tra le varie chiavi troveremo fileReplacements nella sezione architect/build di un singolo progetto.

In entrambe i files sono presenti, di solito, le stesse chiavi ma con valori diversi relativi all’ambiente di sviluppo o di produzione.
Ad esempio, comunemente, potrebbero contenere:

  • URI delle nostre API;
  • SECRET KEYS di vari servizi o API di terze parti;
  • Indirizzi email per eventuali invii di logs;
  • etc…

A questo punto il problema dovrebbe essere piuttosto chiaro:
Se indico i valori, ad esempio, di una SECRET KEY su GitHub, chiunque veda il repository potrà vederla.

La soluzione nascondere (e quindi per rendere sicuro) il tutto che utilizzeremo è piuttosto semplice !

Nell’esempio useremo Redis Patterns Console come progetto al quale abbiamo applicato il workflow delle GitHub Actions.

Redis Patterns Console è una console online interattiva (e reattiva), sviluppata con Angular, per provare e studiare Redis (il database in-memory più famoso al mondo!) ed i suoi più comuni pattern, il tutto direttamente da una web application e quindi senza dover installare e configurare nulla!

Una stella su GitHub ci farebbe davvero felici! :)

La soluzione (o almeno una delle possibili)

La soluzione che propongo non è l’unica ma è certamente rapida ed efficace e si snoda su 4 punti fondamentali.

Creare le environment variables su GitHub con le Secrets

Per evitare tutto ciò utilizzeremo un piccolo script Node.js che eseguiremo, grazie alle GitHub Actions, appena prima del processo di build di Angular così da sostituire al volo i valori del file environment.prod.ts.

I valori che andremo a sostituire, per essere al sicuro da sguardi indiscreti, sarà possibile andarle a memorizzare nelle Secrets del repository GitHub.

Dal repository GitHub clicchiamo sulla tab Settings e successivamente selezioniamo la voce di menù Secrets.

Cliccare sulla tab Settings
Clicchiamo quindi sul menù Secrets

Dalla sezione dei Secrets possiamo creare una nuova coppia chiave/valore che ci consentirà quindi di avere una variabile d’ambiente utilizzabile, tra le altre cose, sulle GitHub Actions!
Cliccando sul bottone New secret, creaimo quindi una chiave, che chiameremo nel nostro caso REDIS_SERVER_API_WS, ed indichiamo il valore opportuno che sarà l’indirizzo delle API del nostro caro Redis.

Sostituire i valori delle environment variables in Angular

Nel file environment.prod.ts, introdotto qualche riga fa, dobbiamo semplicemente andare a variare il valore della chiave di nostro interesse con la chiave che abbiamo indicato nelle Secrets.
Nel nostro caso ad esempio andremo a variare il file (riga 5) nel seguente modo:

Nella riga 5 è stato indicato come valore il nome della chiave della Secrets che abbiamo precedentemente creato.

Come potrete notare, nella chiave redisServer abbiamo indicato come valore (di tipo stringa) REDIS_SERVER_API_WS che altro non è che il nome della Secret che abbiamo creato precedentemente!

Sostituiamo il valore con un piccolo script Node.js

Ciò che dovremo fare a questo punto è aggiungere al nostro repository un file JavaScript, che nel nostro caso sarà .github/workflows/ng-env-replace.js e che non farà altro che sostituire il valore della Secret con il placeholder usato nel file environment.prod.ts di Angular.

Come si può notare, lo script è estremamente banale e non è altro che:

  • Leggere il contenuto del file environment.prod.ts di Angular;
  • Eseguire un replace del placeholder (riga 5), che nel nostro caso è REDIS_SERVER_API_WS, con la environment variable memorizzata nelle Secrets di GitHub;
  • Sovrascrivere il contenuto del file environment.prod.ts di Angular.

Indichiamo l’esecuzione dello script sulla GitHub Action

Dato che tutto il processo avviene nella sandbox creata dalla GitHub Action, il tutto deve anche essere indicato nel file yaml che la descrive:

Come è possibile notare, alla riga 24 (quindi prima del processo di build di Angular) eseguiamo lo script Node.js appena creato, dichiarando alla riga 26 e 27 le environment variables andandole a prelevare dalle Secret.

Così facendo, da questo momento in poi ogni qualvolta verrà eseguita la GitHub Action, l’applicazione verrà compilata correttamente ed in allegria! :D

Conclusioni

In questo modo siamo riusciti quindi a passare ad Angular le environment variables corrette senza esporle direttamente nel repository e quindi in maniera sicura memorizzandole nelle Secrets.
Il processo può chiaramente essere arricchito (ad esempio avendo più variabili e quindi magari ciclandole) o eseguendo dei controlli specifici…ma in fondo il succo non cambia…da questo momento in poi la nostra applicazione Angular potrà essere compilata ogni qualvolta senza alcuno sforzo!

Magico, no? No…semplicemente le GitHub Actions ed i processi di CI/CD in genere lo sono!

Potete vedere il risulato di quanto eseguito dalla GitHub Action visitando direttamente il nostro progetto Redis Patterns Console, e magari cogliere l’occasione per imparare anche Redis!

Per suggerimenti (o aggiunte perché no!), critiche, insulti, lodi, donazioni di enormi quantità di denaro, partite a padel o consigli non serve altro che scrivere nei commenti!

Segui Acadevmy — Software Factory & Learning su Medium, Twitter e Facebook per contattarci o tenerti aggiornato sul mondo dello sviluppo Frontend e DevOps.

--

--

Francesco Sciuti
Devmy
Editor for

CEO@Acadevmy, Google Certified Developer, Projects Manager, Software Engineer, Speaker/Evangelist/Trainer