{"id":15547513,"url":"https://github.com/stefanfreitag/cicd_angular_s3","last_synced_at":"2026-03-14T20:58:12.084Z","repository":{"id":48470540,"uuid":"251107251","full_name":"stefanfreitag/cicd_angular_s3","owner":"stefanfreitag","description":"Simple CI/CD job for an Angular-based appplication","archived":false,"fork":false,"pushed_at":"2024-09-01T11:08:53.000Z","size":2094,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-11-23T02:16:05.250Z","etag":null,"topics":["angular","aws","cdk","codepipeline","s3"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stefanfreitag.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-03-29T18:47:43.000Z","updated_at":"2024-09-01T11:06:42.000Z","dependencies_parsed_at":"2023-12-01T20:30:55.982Z","dependency_job_id":"cdc09de2-994a-42de-93b7-dc7b36261271","html_url":"https://github.com/stefanfreitag/cicd_angular_s3","commit_stats":null,"previous_names":[],"tags_count":36,"template":false,"template_full_name":null,"purl":"pkg:github/stefanfreitag/cicd_angular_s3","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stefanfreitag%2Fcicd_angular_s3","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stefanfreitag%2Fcicd_angular_s3/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stefanfreitag%2Fcicd_angular_s3/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stefanfreitag%2Fcicd_angular_s3/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stefanfreitag","download_url":"https://codeload.github.com/stefanfreitag/cicd_angular_s3/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stefanfreitag%2Fcicd_angular_s3/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28061351,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-26T02:00:06.189Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["angular","aws","cdk","codepipeline","s3"],"created_at":"2024-10-02T13:09:27.264Z","updated_at":"2025-12-26T21:21:51.158Z","avatar_url":"https://github.com/stefanfreitag.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CI/ CD Pipeline for an Angular project\n\nThe [AWS Cloud  Development Kit](https://github.com/aws/aws-cdk) (CDK) is used to build and expose an [Angular](https://angular.io/) application using [AWS CloudFront](https://aws.amazon.com/cloudfront/).\n\n## The source code\n\nThe Angular source code is stored in [one of my GitHub repositories](https://github.com/stefanfreitag/angular-hello-world). It is a very basic application that can be build by executing\n\n```bash\nng build --prod\n```\n\n## The build pipeline\n\nThe build pipeline consists of two stages, the `sourceStage` and the `buildStage`.\n\n```javascript\nconst sourceStage = pipeline.addStage({\n    stageName: \"Source\"\n});\n\nconst buildStage = pipeline.addStage({\n    stageName: \"Build\",\n    placement: {\n    justAfter: sourceStage\n    }\n});\n```\n\nThe `sourceStage` contains only a single action responsible for monitoring changes on the code repository\n\n```javascript\nconst sourceAction = new GitHubSourceAction({\n    actionName: \"GitHub\",\n    owner: \"stefanfreitag\",\n    repo: \"angular-hello-world\",\n    oauthToken: SecretValue.secretsManager(\"my-github-token\"),\n    output: sourceOutput,\n    branch: \"master\",\n    trigger: GitHubTrigger.POLL\n});\n\nsourceStage.addAction(sourceAction);\n```\n\nIn the `buildstage` a CodeBuild project is executed. As part of the project the required software is installed: all required libraries, the AWS as well as the Angular CLI.\n\n```bash\nnpm install\npip install awscli --upgrade --user,\nnpm i -g @angular/cli\"\n```\n\nIn the next phase of the project `ng build --prod` runs and generated the distribution files.\n\nThe last phase is responsible for updating the content of the used S3 bucket.\n\n```bash\naws s3 rm s3://${websiteBucket.bucketName}/ --recursive\naws s3 cp ./dist/angular-hello-world s3://${websiteBucket.bucketName}/ --recursive\n```\n\n## The CloudFront setup\n\nThe S3 bucket `websiteBucket` is not exposed directly to the Internet, CloudFront will be installed in between. Hence the `publicReadAccess`  and `blockPublicAccess` are set to `false` settings.\n\n```javascript\nconst websiteBucket = new Bucket(this, \"bucket\", {\n  websiteIndexDocument: \"index.html\",\n  publicReadAccess: false,\n  encryption: BucketEncryption.S3_MANAGED,\n  blockPublicAccess: {\n    restrictPublicBuckets: false,\n    blockPublicAcls: false,\n    ignorePublicAcls: false,\n    blockPublicPolicy: false,\n  },\n   removalPolicy: RemovalPolicy.DESTROY,\n});\n```\n\nTo allow CloudFront access to the content of the S3 bucket a user is setup\n\n```javascript\nconst oai = new OriginAccessIdentity(this, \"originAccessIdentity\", {\n  comment: \"Allows CloudFront to reach the bucket\",\n});\nwebsiteBucket.grantRead(oai);\n```\n\nThe `CloudFrontWebDistribution` contains aside from the `websiteBucket` and the user information also another bucket used to store the access logs.\n\n```javascript\nnew CloudFrontWebDistribution(this, \"myDistribution\", {\n  originConfigs: [\n    {\n      s3OriginSource: {\n        s3BucketSource: websiteBucket,\n        originAccessIdentity: oai,\n      },\n      behaviors: [{ isDefaultBehavior: true }],\n    }],\n    comment: \"Demo CloudFront Distribution\",\n    loggingConfig: {\n      bucket: accessLogsBucket,\n      prefix: \"ng-s3-demo\",\n      includeCookies: true,\n    },\n    priceClass: PriceClass.PRICE_CLASS_100,\n});\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstefanfreitag%2Fcicd_angular_s3","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstefanfreitag%2Fcicd_angular_s3","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstefanfreitag%2Fcicd_angular_s3/lists"}