Skip to content

Commit

Permalink
Merge branch 'padms/1868-introduce-last-modified-at' into staging
Browse files Browse the repository at this point in the history
  • Loading branch information
padms committed Jul 12, 2024
2 parents b6440ef + 2190cb8 commit 14d412c
Show file tree
Hide file tree
Showing 13 changed files with 393 additions and 53 deletions.
123 changes: 123 additions & 0 deletions .github/workflows/PROD-studios-selected.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
name: PROD - Deploy selected satellite studio
on:
workflow_dispatch:
inputs:
site:
description: 'Name of studio to deploy'
required: true
type: choice
options:
- brazil
- germany
- argentina
- poland
- japan
- storage
- equinorfunds
- southkorea
- celticsea
permissions:
id-token: write
jobs:
update-radix-config:
runs-on: ubuntu-latest
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
steps:
- name: Checkout internal 🛎️
id: checkout-internal
uses: actions/checkout@v3
with:
repository: 'equinor/energyvision-internal'
ref: main
token: ${{ secrets.PADMS_PAT }} # Replace with ssh as per https://stackoverflow.com/questions/60222741/github-actions-and-git-clone-issue
- name: Promote preprod tag to prod 🗒️
if: github.ref == 'refs/heads/main'
shell: bash
id: modify-radix
run: |
# Install pre-requisite
python -m pip install --user ruamel.yaml
python ci/promoteToProduction.py studio ${{ github.event.inputs.site }}
git config --global user.name 'github'
git config --global user.email '[email protected]'
git remote set-url origin https://x-access-token:${{ secrets.PADMS_PAT }}@github.com/equinor/energyvision-internal
if [[ `git status --porcelain` ]]
then
git commit -am "🚀 Deploy ${{ github.event.inputs.site }} to production"
git pull --rebase origin main
git push origin HEAD:main
fi
- uses: act10ns/slack@v2
with:
status: ${{ job.status }}
steps: ${{ toJson(steps) }}
if: failure()

deploy-satellite-studios:
needs: update-radix-config
runs-on: ubuntu-latest
environment:
name: production
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
DOCKER_BUILDKIT: 1
steps:
- name: Checkout 🛎️
uses: actions/checkout@v3

- name: Get token 🔑
id: get-token
uses: ./.github/workflows/get-auth-token/

# PRODUCTION CLUSTERS
- name: Deploy to Radix 🚀
id: deploy
uses: equinor/radix-github-actions@master
with:
args: >
create job
deploy
--token-environment
--context platform2
-a equinor-web-sites
-e ${{ secrets.ENV }}
-f
- uses: act10ns/slack@v2
with:
status: ${{ job.status }}
steps: ${{ toJson(steps) }}
if: failure()

store-image-tags:
needs: deploy-satellite-studios
runs-on: ubuntu-latest
steps:
- name: Checkout internal 🛎️
id: checkout-internal
uses: actions/checkout@v3
with:
repository: 'equinor/energyvision-internal'
ref: main
token: ${{ secrets.PADMS_PAT }}
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: '14' # Or any version you prefer

- name: Install dependencies
run: |
npm install js-yaml
- name: Run script for 'studio'
run: node ci/storeImageTags.js studio

- name: Commit and push changes
run: |
git config --global user.name 'github'
git config --global user.email '[email protected]'
git remote set-url origin https://x-access-token:${{ secrets.PADMS_PAT }}@github.com/equinor/energyvision-internal
git add latest-prod-tags.json
git commit -m "Update latest-prod-tags.json with new tags" || echo "No changes to commit"
git push
55 changes: 15 additions & 40 deletions sanityv3/actions/CustomPublishAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,52 +7,23 @@ import {
DocumentActionsContext,
SanityClient,
} from 'sanity'
import { dataset, apiVersion } from '../sanity.client'
import { apiVersion } from '../sanity.client'
import { useToast } from '@sanity/ui'

const projectId = import.meta.env.SANITY_STUDIO_API_PROJECT_ID || 'h61q9gi9'
/** Secret site already exposes the mutation token. So we can reuse it instead. */
const token = import.meta.env.SANITY_STUDIO_HISTORY_API_TOKEN || import.meta.env.SANITY_STUDIO_MUTATION_TOKEN

const FIRST_PUBLISHED_AT_FIELD_NAME = 'firstPublishedAt'
const LAST_MODIFIED_AT_FIELD_NAME = 'lastModifiedAt'

const requiresConfirm = ['news', 'localNews']
const requiresFirstPublished = ['news', 'localNews', 'magazine']

const shouldAddFirstPublishedAt = async (props: DocumentActionProps) => {
if (!requiresFirstPublished.includes(props.type)) return false
let error = false
// https://github.com/sanity-io/sanity/issues/2179
const revisions = await fetch(
`https://${projectId}.api.sanity.io/${apiVersion}/data/history/${dataset}/transactions/${props.id}?excludeContent=true`,
{
method: 'GET',
headers: new Headers({
Authorization: `Bearer ${token}`,
}),
},
)
.then((res) => res.text())
.catch((err: Error) => {
console.error(err)
error = true
})

if (error) throw 'Failed retrieving history of document.'

const hasBeenPublished = !!revisions

return !hasBeenPublished || !props.published?.[FIRST_PUBLISHED_AT_FIELD_NAME]
}
const updateCustomPublishFields = async (id: string, client: SanityClient, setFirstPublish: boolean) => {
const currentTimeStamp = new Date().toISOString()
const patch = client.patch(id).set({ [LAST_MODIFIED_AT_FIELD_NAME]: currentTimeStamp })
if (setFirstPublish) patch.set({ [FIRST_PUBLISHED_AT_FIELD_NAME]: currentTimeStamp })

const addFirstPublishedAtField = async (id: string, client: SanityClient) => {
await client
.patch(id)
.set({ [FIRST_PUBLISHED_AT_FIELD_NAME]: new Date().toISOString() })
.commit()
.catch((e) => {
throw e
})
await patch.commit().catch((e) => {
throw e
})
}

export function createCustomPublishAction(originalAction: DocumentActionComponent, context: DocumentActionsContext) {
Expand All @@ -64,8 +35,12 @@ export function createCustomPublishAction(originalAction: DocumentActionComponen

const handlePublish = async () => {
try {
if (await shouldAddFirstPublishedAt(props)) {
await addFirstPublishedAtField(props.draft?._id || props.id, client)
if (requiresFirstPublished.includes(props.type)) {
await updateCustomPublishFields(
props.draft?._id || props.id,
client,
!props.published?.[FIRST_PUBLISHED_AT_FIELD_NAME],
)
}
originalResult.onHandle && originalResult.onHandle()
} catch (e) {
Expand Down
8 changes: 8 additions & 0 deletions sanityv3/schemas/documents/magazine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,14 @@ export default {
readOnly: true,
hidden: true,
},
{
// Set automatically in the custom action "ConfirmPublishWithi18n"
title: 'Date and time of when the document was last updated at',
name: 'lastModifiedAt',
type: 'datetime',
readOnly: true,
hidden: true,
},
{
title: 'Meta information',
name: 'seo',
Expand Down
8 changes: 8 additions & 0 deletions sanityv3/schemas/documents/news/sharedNewsFields.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,14 @@ export const publishDateTime = [
readOnly: true,
hidden: true,
},
{
// Set automatically in the custom action "ConfirmPublishWithi18n"
title: 'Date and time of when the document was last updated at',
name: 'lastModifiedAt',
type: 'datetime',
readOnly: true,
hidden: true,
},
]

export const tags = {
Expand Down
28 changes: 28 additions & 0 deletions sanityv3/schemas/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,34 @@ const {
routeHomepage,
} = documentSchemaTypes

const {
pageNotFound,
internalServerError,
assetFile,
assetTag,
countryTag,
event,
eventTag,
landingPage,
footer,
externalRedirect,
localNews,
localNewsTag,
magazine,
magazineTag,
magazineIndex,
route,
redirect,
newsroom,
news,
page,
tag,
subMenu,
siteMenu,
simpleMenu,
routeHomepage,
} = documentSchemaTypes

const routeSchemas = languages.map(({ name, title }) => {
return route(name, title)
})
Expand Down
127 changes: 127 additions & 0 deletions sanityv3/scripts/issue-1868/createMetadataN.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import { sanityClients } from './getSanityClients.mjs'
import { testDocs, SCHEMA_TYPE } from './testDocument.mjs'

/**
* This migration script creates new `translation.metadata` documents for all
* documents that have a `__i18n_refs` field that is an array of references.
*
* This migration is necessary for the new version of the plugin to work.
*
* 1. Take a backup of your dataset with:
* `npx sanity@latest dataset export`
*
* 2. Copy this file to the root of your Sanity Studio project
*
* 3. Update the `UNSET_REFS_FIELD`, `UNSET_BASE_FIELD`,
* and `SCHEMA_TYPE` constants to match your use
*
* 4. Run the script (replace <schema-type> with the name of your schema type):
* npx sanity@latest exec ./createMetadata.ts --with-user-token
*
* 5. Repeat for every schema type and dataset using the updated plugin
*/

const client = sanityClients[0]
// Values in this field will be used to create meta documents
const UNSET_REFS_FIELD = `_langRefs`

// This field will NOT be modified in this script
// Run the `renameLanguageField.ts` script after if you want to change this
const LANGUAGE_FIELD = `_lang`
// eslint-disable-next-line no-console
console.log(
`Finding "${SCHEMA_TYPE}" documents with translation references in a "${UNSET_REFS_FIELD}" field to create "translation.metadata" documents.`,
)

const fetchDocuments = () =>
client.fetch(
`*[
_type in $type
&& (defined(${UNSET_REFS_FIELD}) )
&& defined(${LANGUAGE_FIELD})
][0...100] {
_id,
_rev,
${LANGUAGE_FIELD},
${UNSET_REFS_FIELD},
}`,
{ type: SCHEMA_TYPE, testDocs: testDocs },
)

const buildMetadata = (docs) => {
return docs
.filter((doc) => doc?.[UNSET_REFS_FIELD]?.length)
.map((doc) => {
return {
create: {
_type: 'translation.metadata',
translations: [
{
_key: doc[LANGUAGE_FIELD],
value: {
_type: 'reference',
_ref: doc._id.replace(`drafts.`, ``),
...(doc[UNSET_REFS_FIELD].some((ref) => typeof ref._weak !== 'undefined')
? { _weak: doc[UNSET_REFS_FIELD].find((ref) => ref._weak)?._weak }
: {}),
},
},
...doc[UNSET_REFS_FIELD].map(({ _ref, _key, _weak }) => ({
_key,
value: {
_type: 'reference',
_ref,
...(typeof _weak === 'undefined' ? {} : { _weak }),
},
})),
],
},
patch: {
id: doc._id,
patch: {
unset: [UNSET_REFS_FIELD],
// this will cause the migration to fail if any of the documents has been
// modified since it was fetched.
ifRevisionID: doc._rev,
},
},
}
})
}

const commitTransaction = (tx) => tx.commit()

const migrateNextBatch = async () => {
// Get all docs that match query
const documents = await fetchDocuments()
console.log('Found ' + documents.length + ' docs')

// Create new metadata documents before unsetting
const metadatas = buildMetadata(documents)

if (metadatas.length) {
const tx = client.transaction()
metadatas.forEach((metadata) => {
console.log(JSON.stringify(metadata.patch) + '\n')
return tx.create(metadata.create).patch(metadata.patch.id, metadata.patch.patch)
})
await commitTransaction(tx)
}
if (documents.length === 0) {
// eslint-disable-next-line no-console
console.debug('No more documents to create or patch!')
// eslint-disable-next-line no-console
console.debug(
'Be sure to migrate your "language" field using the "renameLanguageField.ts" script or update your plugin configuration\'s "Langage Field" setting',
)
return null
}
return migrateNextBatch()
}

migrateNextBatch().catch((err) => {
console.error(err)
// eslint-disable-next-line no-process-exit
process.exit(1)
})
Loading

0 comments on commit 14d412c

Please sign in to comment.