diff --git a/.github/workflows/deploy-backend-dev.yml b/.github/workflows/deploy-backend-dev.yml index e49b04cb7..ee523bd36 100644 --- a/.github/workflows/deploy-backend-dev.yml +++ b/.github/workflows/deploy-backend-dev.yml @@ -25,7 +25,7 @@ jobs: role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/github-actions-backend-access aws-region: ap-south-1 - - name: Build backend and deploy to S3 + - name: Build backend and copy zip to S3 run: | apt-get update && apt-get install -y zip GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o main main.go diff --git a/.github/workflows/deploy-backend-prod.yml b/.github/workflows/deploy-backend-prod.yml index c426cd375..8da8b8da4 100644 --- a/.github/workflows/deploy-backend-prod.yml +++ b/.github/workflows/deploy-backend-prod.yml @@ -25,7 +25,7 @@ jobs: role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/github-actions-backend-access aws-region: ap-south-1 - - name: Build backend and deploy to S3 + - name: Build backend and copy zip to S3 run: | apt-get update && apt-get install -y zip GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o main main.go diff --git a/.github/workflows/deploy-frontend-dev.yml b/.github/workflows/deploy-frontend-dev.yml index ea851975a..d9313656e 100644 --- a/.github/workflows/deploy-frontend-dev.yml +++ b/.github/workflows/deploy-frontend-dev.yml @@ -1,8 +1,11 @@ name: DeployFrontendDev on: - push: - branches: + workflow_run: + workflows: ["DeployBackendDev"] + types: + - completed + branches: - "master" jobs: diff --git a/.github/workflows/deploy-frontend-prod.yml b/.github/workflows/deploy-frontend-prod.yml index ef079df49..dcba4e379 100644 --- a/.github/workflows/deploy-frontend-prod.yml +++ b/.github/workflows/deploy-frontend-prod.yml @@ -1,8 +1,11 @@ name: DeployFrontendProd on: - push: - branches: + workflow_run: + workflows: ["DeployBackendProd"] + types: + - completed + branches: - "master" jobs: diff --git a/README.md b/README.md index 8dd733571..f73e571a2 100644 --- a/README.md +++ b/README.md @@ -126,6 +126,9 @@ This repository contains the working code of [Canopas website](https://canopas.c [Here](https://github.com/canopas/canopas-website/blob/master/api-doc.md) is APIs reference used in the website. +### For generating sitemap : +- Add your pages to templates/path.txt + # Canopas website -- Frontend ## Requirements diff --git a/main.go b/main.go index 8e888d8f5..3345cfe9b 100644 --- a/main.go +++ b/main.go @@ -26,6 +26,7 @@ import ( ) //go:embed templates/*.html +//go:embed templates/*.txt var templateFS embed.FS var router *gin.Engine @@ -55,7 +56,7 @@ func setupRouter() *gin.Engine { utilsRepo := utils.NewEmail() contactRepo := contact.New(templateFS, utilsRepo) jobsRepo := jobs.New(sqlDb, templateFS, utilsRepo) - sitemapRepo := sitemap.New(jobsRepo) + sitemapRepo := sitemap.New(jobsRepo, templateFS) leaveRepo := leave.New(templateFS, utilsRepo) notificationRepo := notification.New(templateFS, utilsRepo) lifePerksImagesRepo := jobs.NewLifePerksImages(sqlDb) diff --git a/nuxt-frontend/.prettierignore b/nuxt-frontend/.prettierignore new file mode 100644 index 000000000..7ad30b878 --- /dev/null +++ b/nuxt-frontend/.prettierignore @@ -0,0 +1,2 @@ +*.yml +*.json \ No newline at end of file diff --git a/nuxt-frontend/components/services/WhatWeOfferDesktop.vue b/nuxt-frontend/components/services/WhatWeOfferDesktop.vue index e3273c9b3..666e20078 100644 --- a/nuxt-frontend/components/services/WhatWeOfferDesktop.vue +++ b/nuxt-frontend/components/services/WhatWeOfferDesktop.vue @@ -89,7 +89,7 @@ export default { title: "Flutter App Development ", description: "Bring your multi-platform app vision to life with our Flutter app development services. We excel in crafting high-quality, stunning applications that work flawlessly on Android, iOS, and the web, all from a single codebase, facilitating faster time to market and cost savings.", - url: "/flutter-app-development-ND", + url: "/flutter-app-development", showServices: config.SHOW_FLUTTER_APP_DEVELOPMENT_PAGE, }, { @@ -106,7 +106,7 @@ export default { title: "Backend Development", description: "The 'behind-the-scenes' backbone of any app, the backend, handles the critical tasks of data management, server configuration, and application logic. Our experts ensure your app is robust, secure, and efficient from its core, enabling it to handle high traffic loads, process data swiftly, and interact flawlessly with front-end requests.", - url: "/backend-development-ND", + url: "/backend-development", showServices: config.SHOW_BACKEND_DEVELOPMENT_PAGE, }, { @@ -115,7 +115,7 @@ export default { title: "Frontend Development", description: "The front end is the first point of interaction between your users and your app, making its design and functionality crucial. We focus on creating interactive, visually stunning, and easy-to-navigate interfaces that make your digital presence stand out, promoting enhanced user satisfaction and brand loyalty. ", - url: "/frontend-development-ND", + url: "/frontend-development", showServices: config.SHOW_FRONTEND_DEVELOPMENT_PAGE, }, ], diff --git a/nuxt-frontend/components/services/WhatWeOfferMobile.vue b/nuxt-frontend/components/services/WhatWeOfferMobile.vue index 2166ac024..9b348da03 100644 --- a/nuxt-frontend/components/services/WhatWeOfferMobile.vue +++ b/nuxt-frontend/components/services/WhatWeOfferMobile.vue @@ -87,7 +87,7 @@ export default { "Bring your multi-platform app vision to life with our Flutter app development services. We excel in crafting high-quality, stunning applications that work flawlessly on Android, iOS, and the web, all from a single codebase, facilitating faster time to market and cost savings.", class: "bg-gradient-to-b from-[#E0EDFF] via-[#E0EDFF] to-white bg-gradient-[180deg] ", - url: "/flutter-app-development-ND", + url: "/flutter-app-development", showServices: config.SHOW_FLUTTER_APP_DEVELOPMENT_PAGE, }, { @@ -106,7 +106,7 @@ export default { "The 'behind-the-scenes' backbone of any app, the backend, handles the critical tasks of data management, server configuration, and application logic. Our experts ensure your app is robust, secure, and efficient from its core, enabling it to handle high traffic loads, process data swiftly, and interact flawlessly with front-end requests.", class: "bg-gradient-to-b from-[#D2D8E3]/[0.95] via-[#D2D8E3]/[0.95] to-white bg-gradient-[180deg] ", - url: "/backend-development-ND", + url: "/backend-development", showServices: config.SHOW_BACKEND_DEVELOPMENT_PAGE, }, { @@ -116,7 +116,7 @@ export default { "The front end is the first point of interaction between your users and your app, making its design and functionality crucial. We focus on creating interactive, visually stunning, and easy-to-navigate interfaces that make your digital presence stand out, promoting enhanced user satisfaction and brand loyalty. ", class: "bg-gradient-to-b from-[#BBDEFF] via-[#BBDEFF] to-white bg-gradient-[180deg] ", - url: "/frontend-development-ND", + url: "/frontend-development", showServices: config.SHOW_FRONTEND_DEVELOPMENT_PAGE, }, ], diff --git a/nuxt-frontend/config.js b/nuxt-frontend/config.js index a93839dd2..ab60417d7 100644 --- a/nuxt-frontend/config.js +++ b/nuxt-frontend/config.js @@ -116,7 +116,7 @@ export default Object.freeze({ description: "We create bespoke Flutter applications known for their supreme performance, unwavering security, and outmost reliability", type: "Website", - url: "https://dev-stack.canopas.com/flutter-app-development-ND", + url: "https://dev-stack.canopas.com/flutter-app-development", image: "https://dev-stack.canopas.com/apple-touch-icon.png", }, BACKEND_DEVELOPMENT_SEO_META_DATA: { @@ -124,7 +124,7 @@ export default Object.freeze({ description: "We create bespoke Backend API's known for their supreme performance, unwavering security, and outmost reliability", type: "Website", - url: "https://dev-stack.canopas.com/backend-development-ND", + url: "https://dev-stack.canopas.com/backend-development", image: "https://dev-stack.canopas.com/apple-touch-icon.png", }, FRONTEND_DEVELOPMENT_SEO_META_DATA: { @@ -132,7 +132,7 @@ export default Object.freeze({ description: "We create bespoke Frontend webpages known for their supreme performance, unwavering security, and outmost reliability", type: "Website", - url: "https://dev-stack.canopas.com/frontend-development-ND", + url: "https://dev-stack.canopas.com/frontend-development", image: "https://dev-stack.canopas.com/apple-touch-icon.png", }, IS_PROD: false, diff --git a/nuxt-frontend/config.prod.js b/nuxt-frontend/config.prod.js index d434a04a6..7c83fcfd7 100644 --- a/nuxt-frontend/config.prod.js +++ b/nuxt-frontend/config.prod.js @@ -116,7 +116,7 @@ export default Object.freeze({ description: "We create bespoke Flutter applications known for their supreme performance, unwavering security, and outmost reliability", type: "Website", - url: "https://canopas.com/flutter-app-development-ND", + url: "https://canopas.com/flutter-app-development", image: "https://canopas.com/apple-touch-icon.png", }, BACKEND_DEVELOPMENT_SEO_META_DATA: { @@ -124,7 +124,7 @@ export default Object.freeze({ description: "We create bespoke Backend API's known for their supreme performance, unwavering security, and outmost reliability", type: "Website", - url: "https://canopas.com/backend-development-ND", + url: "https://canopas.com/backend-development", image: "https://canopas.com/apple-touch-icon.png", }, FRONTEND_DEVELOPMENT_SEO_META_DATA: { @@ -132,7 +132,7 @@ export default Object.freeze({ description: "We create bespoke Frontend webpages known for their supreme performance, unwavering security, and outmost reliability", type: "Website", - url: "https://dev-stack.canopas.com/frontend-development-ND", + url: "https://dev-stack.canopas.com/frontend-development", image: "https://dev-stack.canopas.com/apple-touch-icon.png", }, IS_PROD: true, diff --git a/nuxt-frontend/pages/backend-development-ND.vue b/nuxt-frontend/pages/backend-development.vue similarity index 97% rename from nuxt-frontend/pages/backend-development-ND.vue rename to nuxt-frontend/pages/backend-development.vue index f7ea55b34..937adbf80 100644 --- a/nuxt-frontend/pages/backend-development-ND.vue +++ b/nuxt-frontend/pages/backend-development.vue @@ -44,7 +44,7 @@ export default { if (!config.SHOW_BACKEND_DEVELOPMENT_PAGE) { next({ name: "Error404Page", - params: { pathMatch: "/backend-development-ND" }, + params: { pathMatch: "/backend-development" }, }); } else { next(); diff --git a/nuxt-frontend/pages/flutter-app-development-ND.vue b/nuxt-frontend/pages/flutter-app-development.vue similarity index 97% rename from nuxt-frontend/pages/flutter-app-development-ND.vue rename to nuxt-frontend/pages/flutter-app-development.vue index 5db8f2428..dedeea934 100644 --- a/nuxt-frontend/pages/flutter-app-development-ND.vue +++ b/nuxt-frontend/pages/flutter-app-development.vue @@ -49,7 +49,7 @@ export default { if (!config.SHOW_FLUTTER_APP_DEVELOPMENT_PAGE) { next({ name: "Error404Page", - params: { pathMatch: "/flutter-app-development-ND" }, + params: { pathMatch: "/flutter-app-development" }, }); } else { next(); diff --git a/nuxt-frontend/pages/frontend-development-ND.vue b/nuxt-frontend/pages/frontend-development.vue similarity index 96% rename from nuxt-frontend/pages/frontend-development-ND.vue rename to nuxt-frontend/pages/frontend-development.vue index d2b94da4c..cefeb02ca 100644 --- a/nuxt-frontend/pages/frontend-development-ND.vue +++ b/nuxt-frontend/pages/frontend-development.vue @@ -16,7 +16,7 @@ export default { if (!config.SHOW_FRONTEND_DEVELOPMENT_PAGE) { next({ name: "Error404Page", - params: { pathMatch: "/frontend-development-ND" }, + params: { pathMatch: "/frontend-development" }, }); } else { next(); diff --git a/sitemap/sitemap.go b/sitemap/sitemap.go index bec2804c8..a38b3dbc9 100755 --- a/sitemap/sitemap.go +++ b/sitemap/sitemap.go @@ -1,14 +1,16 @@ package sitemap import ( + "bytes" + "embed" "encoding/json" "encoding/xml" - "io/ioutil" + "io" "jobs" "net/http" "os" - "path/filepath" "strings" + "text/template" "time" log "github.com/sirupsen/logrus" @@ -23,10 +25,12 @@ const ( type SitemapRepository struct { careerRepo *jobs.CareerRepository + templates *template.Template } -func New(careerRepo *jobs.CareerRepository) *SitemapRepository { - return &SitemapRepository{careerRepo: careerRepo} +func New(careerRepo *jobs.CareerRepository, templateFs embed.FS) *SitemapRepository { + templates := template.Must(template.ParseFS(templateFs, "templates/*.txt")) + return &SitemapRepository{careerRepo: careerRepo, templates: templates} } type URL struct { @@ -74,24 +78,15 @@ type URLset struct { URL []URL `xml:"url"` } -var testFolderPath string - func (repository *SitemapRepository) GenerateSitemap(c *gin.Context) { baseUrl := c.Query("baseUrl") sitemapUrls := []URL{ {Loc: baseUrl, Priority: `1`}, - {Loc: baseUrl + "/resources", Priority: `0.9`}, - } - - var folderPath string - if testFolderPath != "" { - folderPath = testFolderPath - } else { - folderPath = "nuxt-frontend/pages" } - sitemapUrls, err := repository.addPages(baseUrl, sitemapUrls, folderPath) + filePath := "templates/path.txt" + sitemapUrls, err := repository.addPages(baseUrl, sitemapUrls, filePath) if err != nil { log.Error(err) c.AbortWithStatus(http.StatusInternalServerError) @@ -126,26 +121,40 @@ func (repository *SitemapRepository) GenerateSitemap(c *gin.Context) { c.XML(http.StatusOK, urlset) } -func (repository *SitemapRepository) addPages(baseUrl string, sitemapUrls []URL, folderPath string) ([]URL, error) { - files, err := ioutil.ReadDir(folderPath) +func (repository *SitemapRepository) addPages(baseUrl string, sitemapUrls []URL, file string) ([]URL, error) { + var templateBuffer bytes.Buffer + var input string + + err := repository.templates.ExecuteTemplate(&templateBuffer, "path.txt", input) + if err != nil { - return sitemapUrls, err + log.Error(err) + return sitemapUrls, nil } - for _, file := range files { - if !file.IsDir() { - fileName := file.Name() + fileContent := string(templateBuffer.String()) + lines := strings.Split(fileContent, "\n") + + // append all pages + for _, fileName := range lines { + sitemapUrls = append(sitemapUrls, URL{Loc: baseUrl + "/" + fileName, Priority: "0.9"}) + } - // Check if the file name contains "ND" - if !strings.Contains(fileName, "ND") && !strings.Contains(fileName, "slug") && !strings.Contains(fileName, "index") && !strings.Contains(fileName, "unsubscribe") { - // Extract file name without extension - nameWithoutExt := strings.TrimSuffix(fileName, filepath.Ext(fileName)) + // append jobs + jobsUrl := baseUrl + "/jobs" + sitemapUrls = append(sitemapUrls, URL{Loc: jobsUrl, Priority: `1`}) - // Create URL and append to sitemapUrls - sitemapUrls = append(sitemapUrls, URL{Loc: baseUrl + "/" + nameWithoutExt, Priority: "0.9"}) - } - } + careers, err := repository.careerRepo.GetCareers() + if err != nil { + return sitemapUrls, err } + + for i := range careers { + sitemapUrls = append(sitemapUrls, URL{Loc: jobsUrl + `/` + careers[i].UniqueId, Priority: `0.9`}) + sitemapUrls = append(sitemapUrls, URL{Loc: jobsUrl + `/apply/` + careers[i].UniqueId, Priority: `0.9`}) + } + + // append portfolios portfolioUrl := baseUrl + "/portfolio" portfolios := []Portfolio{ @@ -167,26 +176,13 @@ func (repository *SitemapRepository) addPages(baseUrl string, sitemapUrls []URL, }, } - sitemapUrls = append(sitemapUrls, URL{Loc: portfolioUrl, Priority: `0.9`}) - for i := range portfolios { sitemapUrls = append(sitemapUrls, URL{Loc: portfolioUrl + `/` + portfolios[i].Name, Priority: `0.9`, Video: portfolios[i].Videos}) } - jobsUrl := baseUrl + "/jobs" - sitemapUrls = append(sitemapUrls, URL{Loc: jobsUrl, Priority: `1`}) - - careers, err := repository.careerRepo.GetCareers() - if err != nil { - return sitemapUrls, err - } - - for i := range careers { - sitemapUrls = append(sitemapUrls, URL{Loc: jobsUrl + `/` + careers[i].UniqueId, Priority: `0.9`}) - sitemapUrls = append(sitemapUrls, URL{Loc: jobsUrl + `/apply/` + careers[i].UniqueId, Priority: `0.9`}) - } return sitemapUrls, nil } + func addPublishedResources(baseUrl string, sitemapUrls []URL) ([]URL, error) { resourceUrl := os.Getenv("RESOURCES_URL") @@ -208,7 +204,7 @@ func addPublishedResources(baseUrl string, sitemapUrls []URL) ([]URL, error) { } defer resp.Body.Close() - responseData, err := ioutil.ReadAll(resp.Body) + responseData, err := io.ReadAll(resp.Body) if err != nil { log.Error(err) return sitemapUrls, err diff --git a/sitemap/sitemap_test.go b/sitemap/sitemap_test.go index b35672f7c..49c09a61e 100644 --- a/sitemap/sitemap_test.go +++ b/sitemap/sitemap_test.go @@ -17,6 +17,7 @@ import ( ) //go:embed templates/career-email-template.html +//go:embed templates/path.txt var templateFS embed.FS var repo *SitemapRepository @@ -31,11 +32,10 @@ func TestInit(t *testing.T) { } careerRepo = jobs.New(testDB, templateFS, &stubUtilsRepo{}) - repo = New(careerRepo) + repo = New(careerRepo, templateFS) } func TestSitemap(t *testing.T) { - testFolderPath = "../nuxt-frontend/pages" engine := gin.New() engine.GET("/api/sitemap", repo.GenerateSitemap) req, err := http.NewRequest("GET", "/api/sitemap?baseUrl=http://localhost:8080", nil) @@ -90,22 +90,24 @@ func expectedURLData() []URL { sitemapUrls := []URL{ {Loc: baseUrl, Priority: `1`}, + {Loc: baseUrl + "/services", Priority: `0.9`}, + {Loc: baseUrl + "/portfolio", Priority: `0.9`}, + {Loc: baseUrl + `/contributions`, Priority: `0.9`}, {Loc: baseUrl + "/resources", Priority: `0.9`}, {Loc: baseUrl + "/about", Priority: `0.9`}, - {Loc: baseUrl + "/android-app-development", Priority: `0.9`}, {Loc: baseUrl + "/contact", Priority: `0.9`}, - {Loc: baseUrl + `/contributions`, Priority: `0.9`}, + {Loc: baseUrl + "/android-app-development", Priority: `0.9`}, {Loc: baseUrl + "/ios-app-development", Priority: `0.9`}, {Loc: baseUrl + `/mobile-app-development`, Priority: `0.9`}, - {Loc: baseUrl + `/services`, Priority: `0.9`}, {Loc: baseUrl + `/thank-you`, Priority: `0.9`}, - {Loc: baseUrl + "/portfolio", Priority: `0.9`}, - {Loc: baseUrl + "/portfolio/luxeradio", Priority: `0.9`}, - {Loc: baseUrl + "/portfolio/togness", Priority: `0.9`}, - {Loc: baseUrl + "/portfolio/justly", Priority: `0.9`}, + {Loc: baseUrl + `/jobs/thank-you`, Priority: `0.9`}, + {Loc: baseUrl + `/unsubscribe`, Priority: `0.9`}, {Loc: baseUrl + "/jobs", Priority: `1`}, {Loc: baseUrl + "/jobs/ios-developer-a9b45f34-a1a5-419f-b536-b7c290925d6d", Priority: `0.9`}, {Loc: baseUrl + "/jobs/apply/ios-developer-a9b45f34-a1a5-419f-b536-b7c290925d6d", Priority: `0.9`}, + {Loc: baseUrl + "/portfolio/luxeradio", Priority: `0.9`}, + {Loc: baseUrl + "/portfolio/togness", Priority: `0.9`}, + {Loc: baseUrl + "/portfolio/justly", Priority: `0.9`}, } for i := range sitemapUrls { diff --git a/sitemap/templates/path.txt b/sitemap/templates/path.txt new file mode 100644 index 000000000..6d7f0ab5e --- /dev/null +++ b/sitemap/templates/path.txt @@ -0,0 +1,12 @@ +services +portfolio +contributions +resources +about +contact +android-app-development +ios-app-development +mobile-app-development +thank-you +jobs/thank-you +unsubscribe \ No newline at end of file diff --git a/templates/path.txt b/templates/path.txt new file mode 100644 index 000000000..6d7f0ab5e --- /dev/null +++ b/templates/path.txt @@ -0,0 +1,12 @@ +services +portfolio +contributions +resources +about +contact +android-app-development +ios-app-development +mobile-app-development +thank-you +jobs/thank-you +unsubscribe \ No newline at end of file